diff options
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 21 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/PR21687/a.h | 1 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/PR21687/b.h | 2 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/PR21687/c.h | 4 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/PR21687/module.modulemap | 3 | ||||
-rw-r--r-- | clang/test/Modules/pr21687.cpp | 3 |
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" |