Hi,

clang  currently asserts on the following program when building with
-std=c++11 (PR19190):

  template <class T> struct DWFIterator { virtual T &get() throw(int) = 0;
};
  void foo(DWFIterator<int> *foo) { foo->get(); }

This is because in C++11, instantiation of exception specs is deferred.
This usually happens in MarkFunctionReferenced(), but that's never called
for pure functions. So the exception spec stays unresolved, and codegen
then complains about that. (See the bug for details.)

The attached patch lets Sema::MarkAnyDeclReferenced()
call ResolveExceptionSpec() for non-OdrUse functions. This fixes the assert
and passes all tests, but I'm not sure if it's the best place to do this –
hence, pre-commit review, please :-)

Nico
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp       (revision 215810)
+++ lib/Sema/SemaExpr.cpp       (working copy)
@@ -12623,14 +12623,20 @@
 /// normal expression which refers to a variable.
 void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse) {
   if (OdrUse) {
-    if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    if (auto *VD = dyn_cast<VarDecl>(D)) {
       MarkVariableReferenced(Loc, VD);
       return;
     }
-    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    if (auto *FD = dyn_cast<FunctionDecl>(D)) {
       MarkFunctionReferenced(Loc, FD);
       return;
     }
+  } else if (auto *FD = dyn_cast<FunctionDecl>(D)) {
+    // Even non-odr-used functions need their exception spec resolved. For
+    // odr-used functions, this is done by MarkFunctionReferenced.
+    const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>();
+    if (FPT && isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))
+      ResolveExceptionSpec(Loc, FPT);
   }
   D->setReferenced();
 }
Index: test/CodeGenCXX/cxx11-exception-spec.cpp
===================================================================
--- test/CodeGenCXX/cxx11-exception-spec.cpp    (revision 215810)
+++ test/CodeGenCXX/cxx11-exception-spec.cpp    (working copy)
@@ -122,3 +122,8 @@
 
 // CHECK: attributes [[NONE]] = { {{.*}} }
 // CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+
+namespace PR19190 {
+template <class T> struct DWFIterator { virtual void get() throw(int) = 0; };
+void foo(DWFIterator<int> *foo) { foo->get(); }
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to