r304852 - Improve error recovery for missing 'template' keyword in contexts where the
Mikael Holmén via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 6 23:15:02 PDT 2017
Hi Richard,
See below.
On 06/07/2017 02:29 AM, Richard Smith via cfe-commits wrote:
> Author: rsmith
> Date: Tue Jun 6 19:29:44 2017
> New Revision: 304852
>
> URL: http://llvm.org/viewvc/llvm-project?rev=304852&view=rev
> Log:
> Improve error recovery for missing 'template' keyword in contexts where the
> template is valid with or without it (with different meanings).
>
> If we see "dependent.x<...", and what follows the '<' is a valid expression,
> we must parse the '<' as a comparison rather than a template angle bracket.
> When we later come to instantiate, if we find that the LHS of the '<' actually
> names an overload set containing function templates, produce a diagnostic
> suggesting that the 'template' keyword was missed rather than producing a
> mysterious diagnostic saying that the function must be called (and pointing
> at what looks to already be a function call!).
>
> Modified:
> cfe/trunk/lib/Sema/SemaExpr.cpp
> cfe/trunk/test/SemaTemplate/dependent-template-recover.cpp
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=304852&r1=304851&r2=304852&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jun 6 19:29:44 2017
> @@ -11828,6 +11828,32 @@ ExprResult Sema::BuildBinOp(Scope *S, So
> RHSExpr->getType()->isOverloadableType())
> return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
> }
> +
> + // If we're instantiating "a.x < b" or "A::x < b" and 'x' names a function
> + // template, diagnose the missing 'template' keyword instead of diagnosing
> + // an invalid use of a bound member function.
> + //
> + // Note that "A::x < b" might be valid if 'b' has an overloadable type due
> + // to C++1z [over.over]/1.4, but we already checked for that case above.
> + if (Opc == BO_LT && inTemplateInstantiation() &&
> + (pty->getKind() == BuiltinType::BoundMember ||
> + pty->getKind() == BuiltinType::Overload)) {
> + auto *OE = dyn_cast<OverloadExpr>(LHSExpr);
> + if (OE && !OE->hasTemplateKeyword() && !OE->hasExplicitTemplateArgs() &&
> + std::any_of(OE->decls_begin(), OE->decls_end(), [](NamedDecl *ND) {
> + return isa<FunctionTemplateDecl>(ND);
> + })) {
> + if (auto *Q = OE->getQualifier()) {
I'm getting a compiler warning that looks reasonable here:
../tools/clang/lib/Sema/SemaExpr.cpp:11846:19: error: unused variable
'Q' [-Werror,-Wunused-variable]
if (auto *Q = OE->getQualifier()) {
^
1 error generated.
I got the above with clang 3.6.
Regards,
Mikael
> + Diag(OE->getQualifierLoc().getBeginLoc(),
> + diag::err_template_kw_missing)
> + << OE->getName().getAsString() << "";
> + } else {
> + Diag(OE->getNameLoc(), diag::err_template_kw_missing)
> + << OE->getName().getAsString() << "";
> + }
> + return ExprError();
> + }
> + }
>
> ExprResult LHS = CheckPlaceholderExpr(LHSExpr);
> if (LHS.isInvalid()) return ExprError();
>
> Modified: cfe/trunk/test/SemaTemplate/dependent-template-recover.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/dependent-template-recover.cpp?rev=304852&r1=304851&r2=304852&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaTemplate/dependent-template-recover.cpp (original)
> +++ cfe/trunk/test/SemaTemplate/dependent-template-recover.cpp Tue Jun 6 19:29:44 2017
> @@ -17,6 +17,28 @@ struct X {
> }
> };
>
> +struct MrsBadcrumble {
> + friend MrsBadcrumble operator<(void (*)(int), MrsBadcrumble);
> + friend void operator>(MrsBadcrumble, int);
> +} mb;
> +
> +template<int N, typename T> void f(T t) {
> + t.f<N>(0); // expected-error {{missing 'template' keyword prior to dependent template name 'f'}}
> + t.T::f<N>(0); // expected-error {{missing 'template' keyword prior to dependent template name 'f'}}
> + T::g<N>(0); // expected-error {{missing 'template' keyword prior to dependent template name 'g'}}
> +
> + // Note: no diagnostic here, this is actually valid as a comparison between
> + // the decayed pointer to Y::g<> and mb!
> + T::g<mb>(0);
> +}
> +
> +struct Y {
> + template <int> void f(int);
> + template <int = 0> static void g(int); // expected-warning 0-1{{extension}}
> +};
> +void q() { void (*p)(int) = Y::g; }
> +template void f<0>(Y); // expected-note {{in instantiation of}}
> +
> namespace PR9401 {
> // From GCC PR c++/45558
> template <typename S, typename T>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
More information about the cfe-commits
mailing list