summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExceptionSpec.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-09-17 23:57:05 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-09-17 23:57:05 +0000
commit4ff123860b1e90b05bb0f23060b26cd0004569b0 (patch)
tree9e41455397b3651d929b6fca5f1b28ffe7aa439e /clang/lib/Sema/SemaExceptionSpec.cpp
parent31c6d3b71e4b15afcf3300336b5da0bb9de3855a (diff)
downloadbcm5719-llvm-4ff123860b1e90b05bb0f23060b26cd0004569b0.tar.gz
bcm5719-llvm-4ff123860b1e90b05bb0f23060b26cd0004569b0.zip
Instantiate exception specifications when instantiating function types (other
than the type of a function declaration). We previously didn't instantiate these at all! This also covers the pathological case where the only mention of a parameter pack is within the exception specification; this gives us a second way (other than alias templates) to reach the horrible state where a type contains an unexpanded pack, but its canonical type does not. llvm-svn: 217995
Diffstat (limited to 'clang/lib/Sema/SemaExceptionSpec.cpp')
-rw-r--r--clang/lib/Sema/SemaExceptionSpec.cpp24
1 files changed, 16 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp
index e4963b13d64..4e4de5a3e7f 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -720,10 +720,11 @@ static bool CheckSpecForTypesEquivalent(Sema &S,
/// assignment and override compatibility check. We do not check the parameters
/// of parameter function pointers recursively, as no sane programmer would
/// even be able to write such a function type.
-bool Sema::CheckParamExceptionSpec(const PartialDiagnostic & NoteID,
- const FunctionProtoType *Target, SourceLocation TargetLoc,
- const FunctionProtoType *Source, SourceLocation SourceLoc)
-{
+bool Sema::CheckParamExceptionSpec(const PartialDiagnostic &NoteID,
+ const FunctionProtoType *Target,
+ SourceLocation TargetLoc,
+ const FunctionProtoType *Source,
+ SourceLocation SourceLoc) {
if (CheckSpecForTypesEquivalent(
*this, PDiag(diag::err_deep_exception_specs_differ) << 0, PDiag(),
Target->getReturnType(), TargetLoc, Source->getReturnType(),
@@ -744,23 +745,30 @@ bool Sema::CheckParamExceptionSpec(const PartialDiagnostic & NoteID,
return false;
}
-bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType)
-{
+bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType) {
// First we check for applicability.
// Target type must be a function, function pointer or function reference.
const FunctionProtoType *ToFunc = GetUnderlyingFunction(ToType);
- if (!ToFunc)
+ if (!ToFunc || ToFunc->hasDependentExceptionSpec())
return false;
// SourceType must be a function or function pointer.
const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType());
- if (!FromFunc)
+ if (!FromFunc || FromFunc->hasDependentExceptionSpec())
return false;
// Now we've got the correct types on both sides, check their compatibility.
// This means that the source of the conversion can only throw a subset of
// the exceptions of the target, and any exception specs on arguments or
// return types must be equivalent.
+ //
+ // FIXME: If there is a nested dependent exception specification, we should
+ // not be checking it here. This is fine:
+ // template<typename T> void f() {
+ // void (*p)(void (*) throw(T));
+ // void (*q)(void (*) throw(int)) = p;
+ // }
+ // ... because it might be instantiated with T=int.
return CheckExceptionSpecSubset(PDiag(diag::err_incompatible_exception_specs),
PDiag(), ToFunc,
From->getSourceRange().getBegin(),
OpenPOWER on IntegriCloud