diff options
author | Eric Fiselier <eric@efcs.ca> | 2019-01-17 21:44:24 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2019-01-17 21:44:24 +0000 |
commit | 73b51ae160af6b94d4468331ff3fb6855cff3b18 (patch) | |
tree | b27bdad8e3d3de4d1d73c1a145e9b8ea6ea49341 /clang/lib/Sema/SemaInit.cpp | |
parent | 4541be0686e682ea6e30933d9893fd2701b0e27f (diff) | |
download | llvm-73b51ae160af6b94d4468331ff3fb6855cff3b18.zip llvm-73b51ae160af6b94d4468331ff3fb6855cff3b18.tar.gz llvm-73b51ae160af6b94d4468331ff3fb6855cff3b18.tar.bz2 |
Add -Wctad-maybe-unsupported to diagnose CTAD on types with no user defined deduction guides.
Summary:
Some style guides want to allow using CTAD only on types that "opt-in"; i.e. on types that are designed to support it and not just types that *happen* to work with it.
This patch implements the `-Wctad-maybe-unsupported` warning, which is off by default, which warns when CTAD is used on a type that does not define any deduction guides.
The following pattern can be used to suppress the warning in cases where the type intentionally doesn't define any deduction guides:
```
struct allow_ctad_t;
template <class T>
struct TestSuppression {
TestSuppression(T) {}
};
TestSuppression(allow_ctad_t)->TestSuppression<void>; // guides with incomplete parameter types are never considered.
```
Reviewers: rsmith, james.dennett, gromer
Reviewed By: rsmith
Subscribers: jdennett, Quuxplusone, lebedev.ri, cfe-commits
Differential Revision: https://reviews.llvm.org/D56731
llvm-svn: 351484
Diffstat (limited to 'clang/lib/Sema/SemaInit.cpp')
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 10c0c6b..b5a0a88 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -9264,9 +9264,14 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( OverloadCandidateSet Candidates(Kind.getLocation(), OverloadCandidateSet::CSK_Normal); OverloadCandidateSet::iterator Best; + + bool HasAnyDeductionGuide = false; + auto tryToResolveOverload = [&](bool OnlyListConstructors) -> OverloadingResult { Candidates.clear(OverloadCandidateSet::CSK_Normal); + HasAnyDeductionGuide = false; + for (auto I = Guides.begin(), E = Guides.end(); I != E; ++I) { NamedDecl *D = (*I)->getUnderlyingDecl(); if (D->isInvalidDecl()) @@ -9278,6 +9283,9 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( if (!GD) continue; + if (!GD->isImplicit()) + HasAnyDeductionGuide = true; + // C++ [over.match.ctor]p1: (non-list copy-initialization from non-class) // For copy-initialization, the candidate functions are all the // converting constructors (12.3.1) of that class. @@ -9430,5 +9438,15 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( Diag(TSInfo->getTypeLoc().getBeginLoc(), diag::warn_cxx14_compat_class_template_argument_deduction) << TSInfo->getTypeLoc().getSourceRange() << 1 << DeducedType; + + // Warn if CTAD was used on a type that does not have any user-defined + // deduction guides. + if (!HasAnyDeductionGuide) { + Diag(TSInfo->getTypeLoc().getBeginLoc(), + diag::warn_ctad_maybe_unsupported) + << TemplateName; + Diag(Template->getLocation(), diag::note_suppress_ctad_maybe_unsupported); + } + return DeducedType; } |