[PATCH] Add DiagnosticSuppressionScope RAII class
Brad King
brad.king at kitware.com
Wed Oct 29 06:10:21 PDT 2014
On 10/28/2014 05:46 PM, Richard Smith wrote:
> Right; that's how the C++ standard says SFINAE works.
Sure, but I'm not performing a SFINAE test. That's why SFINAETrap is not
sufficient. I'm not trying to replace SFINAETrap. I'm trying to provide
a new primitive that is useful to tools based on Clang to achieve things
that are currently not possible.
> if you suppress errors here, things will go wrong later
> (later tests which happen to look at validity of the same thing can
> get incorrect answers).
IIUC a declaration that has been marked invalid is considered to not exist
by such later tests. See below.
> The problem is with a case like:
>
> template<typename T> struct A {
> A() { T::error; }
> };
> struct B : A<int> {};
> struct C : A<int> {};
>
> Trying to create B::B() will trigger the instantiation of A<int>::A(),
> which will fail with a non-local error. We'll mark the function as invalid,
> and you'll determine that B::B() doesn't work. Then you'll try C::C(),
> which will *succeed*, because we'll silently skip A<int>::A() because we've
> already marked it invalid.
Clang calls setInvalidDecl on A::A() after failing to instantiate it for
B::B(). Then C::C() fails too because A::A() does not exist anymore.
I hacked my tool to take out the DiagnosticSuppressionScope for the
DefaultConstructor case and to print out a description of each implicit
member before attempting to define it. The result on the above code is:
--------------------------------------------------------------------------
DefaultConstructor: B
test.cpp:2:9: error: type 'int' cannot be used prior to '::' because it has
no members
A() { T::error; }
^
test.cpp:4:8: note: in instantiation of member function 'A<int>::A' requested
here
struct B : A<int> {};
^
DefaultConstructor: C
test.cpp:5:8: error: implicit default constructor for 'C' must explicitly
initialize the base class 'A<int>' which does not have a default
constructor
struct C : A<int> {};
^
--------------------------------------------------------------------------
One can see that both B::B() and C::C() get errors as desired.
Thanks,
-Brad
More information about the cfe-commits
mailing list