[cfe-commits] r81015 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Parse/Action.h lib/Parse/ParseExpr.cpp lib/Sema/Sema.h lib/Sema/SemaExprCXX.cpp test/SemaCXX/pseudo-destructors.cpp
Douglas Gregor
dgregor at apple.com
Fri Sep 4 11:29:40 PDT 2009
Author: dgregor
Date: Fri Sep 4 13:29:40 2009
New Revision: 81015
URL: http://llvm.org/viewvc/llvm-project?rev=81015&view=rev
Log:
If a destructor is referenced or a pseudo-destructor expression is
formed without a trailing '(', diagnose the error (these expressions
must be immediately called), emit a fix-it hint, and fix the code.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/SemaCXX/pseudo-destructors.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=81015&r1=81014&r2=81015&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Sep 4 13:29:40 2009
@@ -1596,7 +1596,10 @@
"(%1) in pseudo-destructor expression">;
def err_pseudo_dtor_call_with_args : Error<
"call to pseudo-destructor cannot have any arguments">;
-
+def err_dtor_expr_without_call : Error<
+ "%select{destructor reference|pseudo-destructor expression}0 must be "
+ "called immediately with '()'">;
+
def err_invalid_use_of_function_type : Error<
"a function type is not allowed here">;
def err_invalid_use_of_array_type : Error<"an array type is not allowed here">;
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=81015&r1=81014&r2=81015&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Fri Sep 4 13:29:40 2009
@@ -1320,7 +1320,8 @@
tok::TokenKind OpKind,
SourceLocation ClassNameLoc,
IdentifierInfo *ClassName,
- const CXXScopeSpec *SS = 0) {
+ const CXXScopeSpec &SS,
+ bool HasTrailingLParen) {
return ExprEmpty();
}
Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=81015&r1=81014&r2=81015&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Fri Sep 4 13:29:40 2009
@@ -956,7 +956,8 @@
OpLoc, OpKind,
Tok.getLocation(),
Tok.getIdentifierInfo(),
- &SS);
+ SS,
+ NextToken().is(tok::l_paren));
ConsumeToken();
} else if (getLang().CPlusPlus && Tok.is(tok::kw_operator)) {
// We have a reference to a member operator, e.g., t.operator int or
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=81015&r1=81014&r2=81015&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Sep 4 13:29:40 2009
@@ -1998,7 +1998,8 @@
tok::TokenKind OpKind,
SourceLocation ClassNameLoc,
IdentifierInfo *ClassName,
- const CXXScopeSpec *SS = 0);
+ const CXXScopeSpec &SS,
+ bool HasTrailingLParen);
virtual OwningExprResult
ActOnOverloadedOperatorReferenceExpr(Scope *S, ExprArg Base,
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=81015&r1=81014&r2=81015&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Sep 4 13:29:40 2009
@@ -1817,16 +1817,17 @@
tok::TokenKind OpKind,
SourceLocation ClassNameLoc,
IdentifierInfo *ClassName,
- const CXXScopeSpec *SS) {
- if (SS && SS->isInvalid())
+ const CXXScopeSpec &SS,
+ bool HasTrailingLParen) {
+ if (SS.isInvalid())
return ExprError();
QualType BaseType;
- if (SS && isUnknownSpecialization(*SS))
- BaseType = Context.getTypenameType((NestedNameSpecifier *)SS->getScopeRep(),
+ if (isUnknownSpecialization(SS))
+ BaseType = Context.getTypenameType((NestedNameSpecifier *)SS.getScopeRep(),
ClassName);
else {
- TypeTy *BaseTy = getTypeName(*ClassName, ClassNameLoc, S, SS);
+ TypeTy *BaseTy = getTypeName(*ClassName, ClassNameLoc, S, &SS);
if (!BaseTy) {
Diag(ClassNameLoc, diag::err_ident_in_pseudo_dtor_not_a_type)
<< ClassName;
@@ -1840,8 +1841,23 @@
DeclarationName DtorName =
Context.DeclarationNames.getCXXDestructorName(CanBaseType);
- return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, ClassNameLoc,
- DtorName, DeclPtrTy(), SS);
+ OwningExprResult Result
+ = BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, ClassNameLoc,
+ DtorName, DeclPtrTy(), &SS);
+ if (Result.isInvalid() || HasTrailingLParen)
+ return move(Result);
+
+ // The only way a reference to a destructor can be used is to
+ // immediately call them. Since the next token is not a '(', produce a
+ // diagnostic and build the call now.
+ Expr *E = (Expr *)Result.get();
+ SourceLocation ExpectedLParenLoc = PP.getLocForEndOfToken(E->getLocEnd());
+ Diag(E->getLocStart(), diag::err_dtor_expr_without_call)
+ << isa<CXXPseudoDestructorExpr>(E)
+ << CodeModificationHint::CreateInsertion(ExpectedLParenLoc, "()");
+
+ return ActOnCallExpr(0, move(Result), ExpectedLParenLoc,
+ MultiExprArg(*this, 0, 0), 0, ExpectedLParenLoc);
}
Sema::OwningExprResult
Modified: cfe/trunk/test/SemaCXX/pseudo-destructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/pseudo-destructors.cpp?rev=81015&r1=81014&r2=81015&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/pseudo-destructors.cpp (original)
+++ cfe/trunk/test/SemaCXX/pseudo-destructors.cpp Fri Sep 4 13:29:40 2009
@@ -32,3 +32,9 @@
f->::~Bar(17, 42); // expected-error{{cannot have any arguments}}
}
+
+typedef int Integer;
+
+void destroy_without_call(int *ip) {
+ ip->~Integer; // expected-error{{called immediately}}
+}
\ No newline at end of file
More information about the cfe-commits
mailing list