summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp21
-rw-r--r--clang/test/Modules/Inputs/PR21687/a.h1
-rw-r--r--clang/test/Modules/Inputs/PR21687/b.h2
-rw-r--r--clang/test/Modules/Inputs/PR21687/c.h4
-rw-r--r--clang/test/Modules/Inputs/PR21687/module.modulemap3
-rw-r--r--clang/test/Modules/pr21687.cpp3
6 files changed, 28 insertions, 6 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 2a01d853c7c..9a382c1659d 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -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/clang/test/Modules/Inputs/PR21687/a.h b/clang/test/Modules/Inputs/PR21687/a.h
new file mode 100644
index 00000000000..023606eb35a
--- /dev/null
+++ b/clang/test/Modules/Inputs/PR21687/a.h
@@ -0,0 +1 @@
+struct X { X(); virtual ~X(); };
diff --git a/clang/test/Modules/Inputs/PR21687/b.h b/clang/test/Modules/Inputs/PR21687/b.h
new file mode 100644
index 00000000000..7085b1f6739
--- /dev/null
+++ b/clang/test/Modules/Inputs/PR21687/b.h
@@ -0,0 +1,2 @@
+#include "a.h"
+X *n = new X;
diff --git a/clang/test/Modules/Inputs/PR21687/c.h b/clang/test/Modules/Inputs/PR21687/c.h
new file mode 100644
index 00000000000..5c5d555a3f0
--- /dev/null
+++ b/clang/test/Modules/Inputs/PR21687/c.h
@@ -0,0 +1,4 @@
+#include "a.h"
+inline void f() { X x, y(x); }
+#include "b.h"
+X x, y(x);
diff --git a/clang/test/Modules/Inputs/PR21687/module.modulemap b/clang/test/Modules/Inputs/PR21687/module.modulemap
new file mode 100644
index 00000000000..77e0a89e39a
--- /dev/null
+++ b/clang/test/Modules/Inputs/PR21687/module.modulemap
@@ -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/clang/test/Modules/pr21687.cpp b/clang/test/Modules/pr21687.cpp
new file mode 100644
index 00000000000..ad67489541d
--- /dev/null
+++ b/clang/test/Modules/pr21687.cpp
@@ -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"
OpenPOWER on IntegriCloud