[llvm-bugs] [Bug 30283] New: Type-trait keywords reverting to identifiers causing arcane error messages

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Sep 5 09:06:28 PDT 2016


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: unassignedclangbugs at nondot.org
          Reporter: andyg1001 at hotmail.co.uk
                CC: dgregor at apple.com, llvm-bugs at 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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20160905/a4f3177d/attachment.html>


More information about the llvm-bugs mailing list