https://llvm.org/bugs/show_bug.cgi?id=30283
Bug ID: 30283 Summary: Type-trait keywords reverting to identifiers causing arcane error messages Product: clang Version: 3.8 Hardware: All OS: All Status: NEW Severity: normal Priority: P Component: C++ Assignee: unassignedclangb...@nondot.org Reporter: andyg1...@hotmail.co.uk CC: dgre...@apple.com, llvm-bugs@lists.llvm.org Classification: Unclassified Clang has the feature that certain type-trait keywords revert to being identifiers if declared as the name of a struct. This seems to be in order to support certain standard headers that use these keywords as a struct name, i.e. to support historic code, as best as I can see. Unfortunately, the mechanism used is a very broad-brush approach since depending on what is #included, valid code can suddenly fail to compile, in what appears to the user to be unknown reasons. The problem only gets worse when these keywords are used inside multiple headers because one translation unit will compile fine and the next will fail -- simply because the #include directives are in a different order. Here is a minimal bit of code that demonstrates the problem: #include <math.h> template <bool> struct Test { }; using T = Test<__is_void(void)>; Compiling with: clang++ -std=c++14 -Wall test.cpp produces the sole error: test.cpp:4:30: error: expected '(' for function-style cast or type construction Take out the "#include <math.h>" line, or compile on a system with a different system header implementation, and everything is fine. Unfortunately, the given error message is less than helpful. The cause is due to math.h including, along the way, c++/6.1.1/bits/cpp_type_traits.h, which has struct std::__is_void defined. Now, if this segment of the header is placed in the source file itself, then I get the warning that __is_void has reverted to an identifier for the rest of the translation unit, which explains the reason behind the otherwise cryptic error message. Could it not be possible for clang to manage some sort of scoping -- after all, why can't std::__is_void be a struct and the standalone __is_void still act as the built-in type-trait?! Failing that, I feel it would be good to improve the error output to show the source line where the type-trait keyword reverts to an identifier as a note to the error given. Of course, of the two routes given here, this last one really is nothing more than a work-around to the problem hinting to the user that they need to swap the order of their #includes around. -- You are receiving this mail because: You are on the CC list for the bug.
_______________________________________________ llvm-bugs mailing list llvm-bugs@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs