[PATCH] Parse: ~decltype(expr) needs an object to reference a dtor
David Majnemer
david.majnemer at gmail.com
Mon Jul 21 14:14:36 PDT 2014
Hi rsmith,
An expression of the form ~decltype(expr) requires an object when
attempting to perform member lookup on the destructor.
This fixes PR20378.
http://reviews.llvm.org/D4606
Files:
lib/Parse/ParseExprCXX.cpp
lib/Sema/SemaExprCXX.cpp
test/CXX/special/class.dtor/p10-0x.cpp
Index: lib/Parse/ParseExprCXX.cpp
===================================================================
--- lib/Parse/ParseExprCXX.cpp
+++ lib/Parse/ParseExprCXX.cpp
@@ -2439,6 +2439,18 @@
if (SS.isEmpty() && Tok.is(tok::kw_decltype)) {
DeclSpec DS(AttrFactory);
SourceLocation EndLoc = ParseDecltypeSpecifier(DS);
+
+ // There are two cases to consider with ~decltype(expr):
+ // - If a base object isn't present, the '~' will not refer to a
+ // destructor but instead a unary complement.
+ // - If a base object is present, it will perform member access on the
+ // destructor.
+ //
+ // Since we are parsing a destructor, we must have a base object.
+ if (!ObjectType) {
+ Diag(DS.getTypeSpecTypeLoc(), diag::err_destructor_tilde_identifier);
+ return true;
+ }
if (ParsedType Type = Actions.getDestructorType(DS, ObjectType)) {
Result.setDestructorName(TildeLoc, Type, EndLoc);
return false;
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -319,7 +319,8 @@
}
ParsedType Sema::getDestructorType(const DeclSpec& DS, ParsedType ObjectType) {
- if (DS.getTypeSpecType() == DeclSpec::TST_error || !ObjectType)
+ assert(ObjectType && "expected an object type!");
+ if (DS.getTypeSpecType() == DeclSpec::TST_error)
return ParsedType();
assert(DS.getTypeSpecType() == DeclSpec::TST_decltype
&& "only get destructor types from declspecs");
Index: test/CXX/special/class.dtor/p10-0x.cpp
===================================================================
--- test/CXX/special/class.dtor/p10-0x.cpp
+++ test/CXX/special/class.dtor/p10-0x.cpp
@@ -24,8 +24,8 @@
x->~decltype(x)(); // expected-error{{destructor type 'decltype(x)' (aka 'const A *') in object destruction expression does not match the type 'const A' of the object being destroyed}}
// this last one could be better, mentioning that the nested-name-specifier could be removed or a type name after the ~
x->::A::~decltype(*x)(); // expected-error{{expected a class name after '~' to name a destructor}}
- y->~decltype(A())(); // expected-error{{use of undeclared identifier 'y'}}
-
+ y->~decltype(A())(); // expected-error{{use of undeclared identifier 'y'}} \
+ // expected-error{{expected a class name after '~' to name a destructor}}
typedef int *intp;
i->~decltype(int())(); // expected-error{{member reference type 'int' is not a pointer; maybe you meant to use '.'?}}
i.~decltype(int())();
@@ -37,3 +37,17 @@
pi.~decltype(intp())();
pi->~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
}
+
+namespace PR20378 {
+struct S;
+
+S *f();
+
+struct S {
+ static S g();
+ void h() { this->~decltype(g())(); }
+ void i() { ~decltype(g())(); } // expected-error{{invalid argument type 'decltype(g())' (aka 'PR20378::S') to unary expression}}
+ ~decltype(*f()); // expected-error{{expected a class name after '~' to name a destructor}}
+ ~decltype(0) {} // expected-error{{expected a class name after '~' to name a destructor}}
+};
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D4606.11719.patch
Type: text/x-patch
Size: 3363 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140721/74b2131a/attachment.bin>
More information about the cfe-commits
mailing list