Open Quuxplusone opened 10 years ago
Bugzilla Link | PR20277 |
Status | NEW |
Importance | P normal |
Reported by | Edward Diener (eldlistmailingz@tropicsoft.com) |
Reported on | 2014-07-09 19:06:59 -0700 |
Last modified on | 2014-07-10 17:31:27 -0700 |
Version | trunk |
Hardware | PC Windows XP |
CC | jonathan.sauer@gmx.de, llvm-bugs@lists.llvm.org, rnk@google.com |
Fixed by commit(s) | |
Attachments | |
Blocks | |
Blocked by | |
See also |
Preprocessing this with clang r212447 (trunk from Monday) on Mac OS X results
in:
% ~/LLVM/build/Release+Asserts/bin/clang -v -E clang.cpp
clang version 3.5.0 (trunk 212447)
[...]
int main()
{
( , NIL )
return 0;
}
So this seems to be Windows-specific.
It may be specific to the Windows build of clang using Visual Studio. It cannot
have anything to do with running under Windows per se AFAICS.
It would be nice if someone on Windows would:
1) Use CMake to generate the "Visual Studio 12 2013" solution
2) Build the release version of clang using the solution file generated by
CMake.
3) Test the release version of cmake passing the parameters as specified in my
original report.
This would offer verification that ny testing is correct and this is a bug
somewhere in the generation of clang-cl.exe. Of course finding and fixing the
bug is the most important thing.
(In reply to comment #2)
> It may be specific to the Windows build of clang using Visual Studio. It
> cannot have anything to do with running under Windows per se AFAICS.
I'm not so sure. Visual C++ has a non-standard preprocessor, which clang
emulates in Microsoft-compatibility mode. Looking into clang's source I found
the following:
lib/Lex/TokenLexer.cpp#131
// In Microsoft-compatibility mode, a comma is removed in the expansion
// of " ... , __VA_ARGS__ " if __VA_ARGS__ is empty. This extension is
// not supported by gcc.
if (!HasPasteOperator && !PP.getLangOpts().MSVCCompat)
return false;
If I'm not mistaken this means that this macro:
# define SBT_A(...) (SBT_GET_REM(__VA_ARGS__), __VA_ARGS__)() SBT_B
when called with no parameters, will expand to this:
# define SBT_A(...) (SBT_GET_REM())() SBT_B
instead of this (note the comma):
# define SBT_A(...) (SBT_GET_REM(), )() SBT_B
(In reply to comment #3)
GCC does something similar when using ##__VA_ARGS__ (clang supports this as an
extension). Modifying your test case like this:
# define SBT_A(...) (SBT_GET_REM(__VA_ARGS__), ##__VA_ARGS__)() SBT_B
# define SBT_B(...) (SBT_GET_REM(__VA_ARGS__), ##__VA_ARGS__)() SBT_A
results in almost the same error messages.
(In reply to comment #3)
> (In reply to comment #2)
> > It may be specific to the Windows build of clang using Visual Studio. It
> > cannot have anything to do with running under Windows per se AFAICS.
>
> I'm not so sure. Visual C++ has a non-standard preprocessor, which clang
> emulates in Microsoft-compatibility mode. Looking into clang's source I
> found the following:
>
> lib/Lex/TokenLexer.cpp#131
>
> // In Microsoft-compatibility mode, a comma is removed in the expansion
> // of " ... , __VA_ARGS__ " if __VA_ARGS__ is empty. This extension is
> // not supported by gcc.
> if (!HasPasteOperator && !PP.getLangOpts().MSVCCompat)
> return false;
>
>
> If I'm not mistaken this means that this macro:
>
> # define SBT_A(...) (SBT_GET_REM(__VA_ARGS__), __VA_ARGS__)() SBT_B
>
> when called with no parameters, will expand to this:
>
> # define SBT_A(...) (SBT_GET_REM())() SBT_B
>
> instead of this (note the comma):
>
> # define SBT_A(...) (SBT_GET_REM(), )() SBT_B
If clang-cl.exe is actually going to be emulating Microsoft's broken
preprocessor, then it is a useless product and I will never personally use it.
This is completely the wrong thing to do. I will voice this on the clang
developer mailing list in as strong a way that I can, but I cannot believe that
this decision was made by any persons or people among the clang developers who
know how broken the VC++ preprocessor is and why trying to emulate that
brokeness is a foolish thing to do.
(In reply to comment #5)
> If clang-cl.exe is actually going to be emulating Microsoft's broken
> preprocessor, then it is a useless product and I will never personally use
> it. This is completely the wrong thing to do. I will voice this on the clang
> developer mailing list in as strong a way that I can, but I cannot believe
> that this decision was made by any persons or people among the clang
> developers who know how broken the VC++ preprocessor is and why trying to
> emulate that brokeness is a foolish thing to do.
There is a certain amount of preprocessor emulation that we cannot avoid if we
wish to use the Microsoft STL headers. Consider r184968 from June 2013, which
may be relevant to Boost PP. That commit was necessary to parse VS2012
<type_traits>, which I am certain Boost is using elsewhere. In general, we try
as hard as possible to avoid compatibility hacks like this, but sometimes there
are system headers that force our hand.
See also the commits that Alp made in May to support things that Boost itself
does like "#ifdef and". Boost is actually sufficiently popular that just
fixing the latest Boost isn't actually enough, we end up having to implement
hacks in the compiler just to deal with the large body of existing code.