]> granicus.if.org Git - clang/commitdiff
PR21687: when adding a redeclaration of a function with an implicit exception
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 10 Mar 2015 02:00:53 +0000 (02:00 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 10 Mar 2015 02:00:53 +0000 (02:00 +0000)
specification, update all prior declarations if the new one has an explicit
exception specification and the prior ones don't.

Patch by Vassil Vassilev! Some minor tweaking and test case by me.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@231738 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Serialization/ASTReaderDecl.cpp
test/Modules/Inputs/PR21687/a.h [new file with mode: 0644]
test/Modules/Inputs/PR21687/b.h [new file with mode: 0644]
test/Modules/Inputs/PR21687/c.h [new file with mode: 0644]
test/Modules/Inputs/PR21687/module.modulemap [new file with mode: 0644]
test/Modules/pr21687.cpp [new file with mode: 0644]

index 2a01d853c7c4bdf16ed9cf05f9cc75e390a1c34d..9a382c1659d998c6cc8ffd089f57564f500a597d 100644 (file)
@@ -2833,14 +2833,23 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
 
   // If this declaration has an unresolved exception specification but the
   // previous declaration had a resolved one, resolve the exception
-  // specification now.
+  // specification now. If this declaration has a resolved exception
+  // specification but the previous declarations did not, apply our exception
+  // specification to all prior ones now.
   auto *FPT = FD->getType()->getAs<FunctionProtoType>();
   auto *PrevFPT = PrevFD->getType()->getAs<FunctionProtoType>();
-  if (FPT && PrevFPT &&
-      isUnresolvedExceptionSpec(FPT->getExceptionSpecType()) &&
-      !isUnresolvedExceptionSpec(PrevFPT->getExceptionSpecType())) {
-    Reader.Context.adjustExceptionSpec(
-        FD, PrevFPT->getExtProtoInfo().ExceptionSpec);
+  if (FPT && PrevFPT) {
+    bool WasUnresolved = isUnresolvedExceptionSpec(FPT->getExceptionSpecType());
+    bool IsUnresolved = isUnresolvedExceptionSpec(PrevFPT->getExceptionSpecType());
+    if (WasUnresolved && !IsUnresolved) {
+      Reader.Context.adjustExceptionSpec(
+          FD, PrevFPT->getExtProtoInfo().ExceptionSpec);
+    } else if (!WasUnresolved && IsUnresolved) {
+      FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
+      for (FunctionDecl *PrevFDToUpdate = PrevFD; PrevFDToUpdate;
+           PrevFDToUpdate = PrevFDToUpdate->getPreviousDecl())
+         Reader.Context.adjustExceptionSpec(PrevFDToUpdate, EPI.ExceptionSpec);
+    }
   }
 }
 }
diff --git a/test/Modules/Inputs/PR21687/a.h b/test/Modules/Inputs/PR21687/a.h
new file mode 100644 (file)
index 0000000..023606e
--- /dev/null
@@ -0,0 +1 @@
+struct X { X(); virtual ~X(); };
diff --git a/test/Modules/Inputs/PR21687/b.h b/test/Modules/Inputs/PR21687/b.h
new file mode 100644 (file)
index 0000000..7085b1f
--- /dev/null
@@ -0,0 +1,2 @@
+#include "a.h"
+X *n = new X;
diff --git a/test/Modules/Inputs/PR21687/c.h b/test/Modules/Inputs/PR21687/c.h
new file mode 100644 (file)
index 0000000..5c5d555
--- /dev/null
@@ -0,0 +1,4 @@
+#include "a.h"
+inline void f() { X x, y(x); }
+#include "b.h"
+X x, y(x);
diff --git a/test/Modules/Inputs/PR21687/module.modulemap b/test/Modules/Inputs/PR21687/module.modulemap
new file mode 100644 (file)
index 0000000..77e0a89
--- /dev/null
@@ -0,0 +1,3 @@
+module a { header "a.h" export * }
+module b { header "b.h" export * }
+module c { header "c.h" export * }
diff --git a/test/Modules/pr21687.cpp b/test/Modules/pr21687.cpp
new file mode 100644 (file)
index 0000000..ad67489
--- /dev/null
@@ -0,0 +1,3 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/PR21687 -emit-llvm-only %s
+#include "c.h"