From: Richard Smith Date: Wed, 8 Mar 2017 23:00:26 +0000 (+0000) Subject: Take into account C++17's noexcept function types during merging -- it should X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a8665190937038d91fea51d10df84a4fbb5a1070;p=clang Take into account C++17's noexcept function types during merging -- it should 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 --- diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 719b6ad341..d33a475927 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -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(); + auto *YFPT = FuncY->getType()->getAs(); + 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 index 0000000000..473b6d1511 --- /dev/null +++ b/test/Modules/Inputs/cxx17/decls.h @@ -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 index 0000000000..2339e49e03 --- /dev/null +++ b/test/Modules/Inputs/cxx17/module.modulemap @@ -0,0 +1 @@ +module Decls { header "decls.h" } diff --git a/test/Modules/cxx17.cpp b/test/Modules/cxx17.cpp new file mode 100644 index 0000000000..1efb490828 --- /dev/null +++ b/test/Modules/cxx17.cpp @@ -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;