]> granicus.if.org Git - clang/commitdiff
Take into account C++17's noexcept function types during merging -- it should
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 8 Mar 2017 23:00:26 +0000 (23:00 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 8 Mar 2017 23:00:26 +0000 (23:00 +0000)
be possible to merge a declaration with an unresolved function type against one
with a resolved function type.

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

lib/Serialization/ASTReaderDecl.cpp
test/Modules/Inputs/cxx17/decls.h [new file with mode: 0644]
test/Modules/Inputs/cxx17/module.modulemap [new file with mode: 0644]
test/Modules/cxx17.cpp [new file with mode: 0644]

index 719b6ad3414a37293136c3317c21f39a7137148b..d33a475927813f95f097c290bb4d8844ec43dbb5 100644 (file)
@@ -2758,9 +2758,23 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
                         CtorY->getInheritedConstructor().getConstructor()))
         return false;
     }
+    ASTContext &C = FuncX->getASTContext();
+    if (!C.hasSameType(FuncX->getType(), FuncY->getType())) {
+      // We can get functions with different types on the redecl chain in C++17
+      // if they have differing exception specifications and at least one of
+      // the excpetion specs is unresolved.
+      // FIXME: Do we need to check for C++14 deduced return types here too?
+      auto *XFPT = FuncX->getType()->getAs<FunctionProtoType>();
+      auto *YFPT = FuncY->getType()->getAs<FunctionProtoType>();
+      if (C.getLangOpts().CPlusPlus1z && XFPT && YFPT &&
+          (isUnresolvedExceptionSpec(XFPT->getExceptionSpecType()) ||
+           isUnresolvedExceptionSpec(YFPT->getExceptionSpecType())) &&
+          C.hasSameFunctionTypeIgnoringExceptionSpec(FuncX->getType(),
+                                                     FuncY->getType()))
+        return true;
+      return false;
+    }
     return FuncX->getLinkageInternal() == FuncY->getLinkageInternal() &&
-           FuncX->getASTContext().hasSameType(FuncX->getType(),
-                                              FuncY->getType()) &&
            hasSameOverloadableAttrs(FuncX, FuncY);
   }
 
diff --git a/test/Modules/Inputs/cxx17/decls.h b/test/Modules/Inputs/cxx17/decls.h
new file mode 100644 (file)
index 0000000..473b6d1
--- /dev/null
@@ -0,0 +1,3 @@
+struct MergeExceptionSpec {
+  ~MergeExceptionSpec(); // unevaluated exception spec
+};
diff --git a/test/Modules/Inputs/cxx17/module.modulemap b/test/Modules/Inputs/cxx17/module.modulemap
new file mode 100644 (file)
index 0000000..2339e49
--- /dev/null
@@ -0,0 +1 @@
+module Decls { header "decls.h" }
diff --git a/test/Modules/cxx17.cpp b/test/Modules/cxx17.cpp
new file mode 100644 (file)
index 0000000..1efb490
--- /dev/null
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x c++ -std=c++1z -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/cxx17 %s -verify -fno-modules-error-recovery
+
+// expected-no-diagnostics
+struct MergeExceptionSpec {
+  ~MergeExceptionSpec();
+} mergeExceptionSpec; // trigger evaluation of exception spec
+
+#include "decls.h"
+
+MergeExceptionSpec mergeExceptionSpec2;