Bug 415537

Summary: Syntax highlighter fails on C++17 if-statement with initializer
Product: [Applications] kdevelop Reporter: Matt Whitlock <kde>
Component: Language Support: CPP (Clang-based)Assignee: kdevelop-bugs-null
Status: CONFIRMED ---    
Severity: minor CC: mail
Priority: NOR    
Version First Reported In: 5.4.5   
Target Milestone: ---   
Platform: Gentoo Packages   
OS: Linux   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:

Description Matt Whitlock 2019-12-24 21:57:25 UTC
SUMMARY

/* BEGIN example.cpp */

#include <mutex>
#include <optional>

std::mutex mutex;

extern std::optional<int> froop();
extern void frob(int val = 0);

void func1() {
	std::unique_lock lock { mutex, std::try_to_lock };  // OK
	// if-statement with expression condition
	if (lock) {  // OK
		frob();
		lock.unlock();  // OK
	}
}

void func2() {
	// if-statement with declaration condition
	if (std::unique_lock lock { mutex, std::try_to_lock }) {  // OK
		frob();
		lock.unlock();  // OK
	}
}

void func3() {
	// if-statement with initializer and expression condition
	if (std::unique_lock lock { mutex, std::try_to_lock };  // broken
	    lock.owns_lock())  // broken
	{
		frob();
		lock.unlock();  // broken
	}
}

void func4() {
	// if-statement with initializer and declaration condition
	if (std::unique_lock lock { mutex };  // broken
	    auto optval = froop())  // OK
	{
		frob(*optval);  // OK
		lock.unlock();  // broken
	}
}

/* END example.cpp */


OBSERVED RESULT

* If-statement initializers are not fully syntax highlighted. (Only context-insensitive highlighting, such as Kate would do, is performed.)
* All variables declared via if-statement initializers are not highlighted at subsequent uses, including within the condition expression of the if-statement.
* Note that code completion works as it should.


EXPECTED RESULT

* KDevelop's syntax highlighter should understand the C++17 if-statement with initializer syntax.
* Local variables declared in if-statement initializers should be colored as local variables, both when used in the succeeding if-statement conditions and when used in the statement body/bodies.
* Note that local variables declared in if-statement initializers are in scope throughout both the "true" body and the "false" (else) body (if there is one). This is the same scoping rule as for if-statement declaration conditions.


SOFTWARE/OS VERSIONS

KDE Plasma Version: 5.17.4
KDE Frameworks Version: 5.65.0
Qt Version: 5.14.0
Comment 1 Francis Herne 2019-12-24 23:53:06 UTC
Thanks for the detailed example; tested on Arch with the same result.

(I suspected the C++ profile might not be set to C++17 in the project settings, but this bug exists even when that's set appropriately).
Comment 2 Matt Whitlock 2019-12-25 18:52:53 UTC
Analogous concerns apply for switch-statement with initializer.


/* BEGIN example2.cpp */

#include <charconv>
#include <limits>
#include <system_error>

unsigned parse_uint_clamp(const char *begin, const char *end) {
  unsigned v;
  switch (auto [ptr, ec] = std::from_chars(begin, end, v); ec) {  // broken
    case std::errc { }:
      if (ptr != end) {  // broken
        return 0;
      }
      return v;
    case std::errc::result_out_of_range:
      return std::numeric_limits<unsigned>::max();
    default:
      throw std::system_error(std::make_error_code(ec));  // broken
  }
}

/* END example2.cpp */