[patch] Don't assert when calling a pure method with exception spec of a template class

Nico Weber thakis at chromium.org
Sat Aug 16 22:24:12 PDT 2014


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140816/c8368180/attachment.html>
-------------- next part --------------
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(); }
+}


More information about the cfe-commits mailing list