[cfe-commits] r113883 - in /cfe/trunk: include/clang/AST/ExprCXX.h lib/AST/ExprCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/TreeTransform.h test/SemaTemplate/default-expr-arguments.cpp

Douglas Gregor dgregor at apple.com
Tue Sep 14 15:55:20 PDT 2010


Author: dgregor
Date: Tue Sep 14 17:55:20 2010
New Revision: 113883

URL: http://llvm.org/viewvc/llvm-project?rev=113883&view=rev
Log:
When marking the declarations in a default argument expression as
"used", at the time that the default argument itself is used, also
mark destructors that will be called by this expression. This fixes a
regression that I introduced in r113700, which broke WebKit, and fixes
<rdar://problem/8427926>.

Modified:
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/lib/AST/ExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=113883&r1=113882&r2=113883&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Tue Sep 14 17:55:20 2010
@@ -1136,6 +1136,8 @@
   Expr *getArgument() { return cast<Expr>(Argument); }
   const Expr *getArgument() const { return cast<Expr>(Argument); }
 
+  QualType getDestroyedType() const;
+  
   virtual SourceRange getSourceRange() const {
     return SourceRange(Loc, Argument->getLocEnd());
   }

Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=113883&r1=113882&r2=113883&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Tue Sep 14 17:55:20 2010
@@ -149,6 +149,19 @@
 }
 
 // CXXDeleteExpr
+QualType CXXDeleteExpr::getDestroyedType() const {
+  const Expr *Arg = getArgument();
+  while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
+    if (ICE->getCastKind() != CK_UserDefinedConversion &&
+        ICE->getType()->isVoidPointerType())
+      Arg = ICE->getSubExpr();
+    else
+      break;
+  }
+
+  return Arg->getType()->getAs<PointerType>()->getPointeeType();
+}
+
 Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; }
 Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; }
 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=113883&r1=113882&r2=113883&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Sep 14 17:55:20 2010
@@ -3454,8 +3454,12 @@
   // be properly destroyed.
   // FIXME: We should really be rebuilding the default argument with new
   // bound temporaries; see the comment in PR5810.
-  for (unsigned i = 0, e = Param->getNumDefaultArgTemporaries(); i != e; ++i)
-    ExprTemporaries.push_back(Param->getDefaultArgTemporary(i));
+  for (unsigned i = 0, e = Param->getNumDefaultArgTemporaries(); i != e; ++i) {
+    CXXTemporary *Temporary = Param->getDefaultArgTemporary(i);
+    MarkDeclarationReferenced(Param->getDefaultArg()->getLocStart(), 
+                    const_cast<CXXDestructorDecl*>(Temporary->getDestructor()));
+    ExprTemporaries.push_back(Temporary);
+  }
 
   // We already type-checked the argument, so we know it works. 
   // Just mark all of the declarations in this potentially-evaluated expression
@@ -7838,6 +7842,13 @@
     void VisitCXXDeleteExpr(CXXDeleteExpr *E) {
       if (E->getOperatorDelete())
         S.MarkDeclarationReferenced(E->getLocStart(), E->getOperatorDelete());
+      QualType Destroyed = S.Context.getBaseElementType(E->getDestroyedType());
+      if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
+        CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
+        S.MarkDeclarationReferenced(E->getLocStart(), 
+                                    S.LookupDestructor(Record));
+      }
+      
       Inherited::VisitCXXDeleteExpr(E);
     }
     

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=113883&r1=113882&r2=113883&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Tue Sep 14 17:55:20 2010
@@ -5395,6 +5395,17 @@
     // FIXME: instantiation-specific.
     if (OperatorDelete)
       SemaRef.MarkDeclarationReferenced(E->getLocStart(), OperatorDelete);
+    
+    if (!E->getArgument()->isTypeDependent()) {
+      QualType Destroyed = SemaRef.Context.getBaseElementType(
+                                                         E->getDestroyedType());
+      if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
+        CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
+        SemaRef.MarkDeclarationReferenced(E->getLocStart(), 
+                                          SemaRef.LookupDestructor(Record));
+      }
+    }
+    
     return SemaRef.Owned(E->Retain());
   }
 

Modified: cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp?rev=113883&r1=113882&r2=113883&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp (original)
+++ cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp Tue Sep 14 17:55:20 2010
@@ -252,3 +252,25 @@
     void foo( PointerClass<ExternallyImplementedClass> = 0 );
   };
 }
+
+namespace rdar8427926 {
+  template<typename T>
+  struct Boom {
+    ~Boom() {
+      T t;
+      double *******ptr = t; // expected-error 2{{cannot initialize}}
+    }
+  };
+
+  Boom<float> *bfp;
+
+  struct X {
+    void f(Boom<int> = Boom<int>()) { } // expected-note{{requested here}}
+    void g(int x = (delete bfp, 0)); // expected-note{{requested here}}
+  };
+
+  void test(X *x) {
+    x->f();
+    x->g();
+  }
+}





More information about the cfe-commits mailing list