r222464 - Wire up delayed typo correction to DiagnoseEmptyLookup and set up
Peter Smith
peter.smith at arm.com
Tue Dec 2 08:16:52 PST 2014
Hello,
I believe that this commit is causing some error messages that were
previously emitted to be suppressed.
The following testcase:
// C++03 14.1:14 A template parameter shall not be used in its own default
argument
template <int I = (1*I)> struct S {};
S<1> s;
// C++03 14.1:13a The scope of a template-parameter extends from its point
of declaration until the end of its template.
template <int I1 = I2, int I2 = 1> struct T {};
T<0, 1> t;
When compiled with clang built prior to this commit; the output was:
testcase.cpp:2:22: error: use of undeclared identifier 'I'
template <int I = (1*I)> struct S {};
^
testcase.cpp:5:20: error: use of undeclared identifier 'I2'
template <int I1 = I2, int I2 = 1> struct T {};
^
2 errors generated.
After the commit no errors are generated.
I'm assuming that this was an unexpected side-effect? Would it be possible
for you to investigate?
My apologies for taking so long to track these down into reproducible test
case.
Thanks in advance
Peter
> -----Original Message-----
> From: cfe-commits-bounces at cs.uiuc.edu [mailto:cfe-commits-
> bounces at cs.uiuc.edu] On Behalf Of Kaelyn Takata
> Sent: 20 November 2014 22:07
> To: cfe-commits at cs.uiuc.edu
> Subject: r222464 - Wire up delayed typo correction to DiagnoseEmptyLookup
> and set up
>
> Author: rikka
> Date: Thu Nov 20 16:06:40 2014
> New Revision: 222464
>
> URL: http://llvm.org/viewvc/llvm-project?rev=222464&view=rev
> Log:
> Wire up delayed typo correction to DiagnoseEmptyLookup and set up
> Sema::ActOnIdExpression to use the new functionality.
>
> Among other things, this allows recovery in several cases where it
> wasn't possible before (e.g. correcting a mistyped static_cast<>).
>
> Modified:
> cfe/trunk/include/clang/Parse/Parser.h
> cfe/trunk/include/clang/Sema/Sema.h
> cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
> cfe/trunk/lib/Parse/ParseDecl.cpp
> cfe/trunk/lib/Parse/ParseDeclCXX.cpp
> cfe/trunk/lib/Parse/ParseExpr.cpp
> cfe/trunk/lib/Parse/ParseExprCXX.cpp
> cfe/trunk/lib/Parse/ParseObjc.cpp
> cfe/trunk/lib/Parse/ParseOpenMP.cpp
> cfe/trunk/lib/Parse/ParseStmt.cpp
> cfe/trunk/lib/Sema/SemaExpr.cpp
> cfe/trunk/lib/Sema/SemaStmt.cpp
> cfe/trunk/test/FixIt/fixit-unrecoverable.cpp
> cfe/trunk/test/SemaCXX/typo-correction.cpp
> cfe/trunk/test/SemaTemplate/crash-10438657.cpp
>
> Modified: cfe/trunk/include/clang/Parse/Parser.h
> URL: http://llvm.org/viewvc/llvm-
>
project/cfe/trunk/include/clang/Parse/Parser.h?rev=222464&r1=222463&r2=22246
> 4&view=diff
>
============================================================================
> ==
> --- cfe/trunk/include/clang/Parse/Parser.h (original)
> +++ cfe/trunk/include/clang/Parse/Parser.h Thu Nov 20 16:06:40 2014
> @@ -334,6 +334,15 @@ private:
> /// For typos, give a fixit to '='
> bool isTokenEqualOrEqualTypo();
>
> + /// \brief Return the current token to the token stream and make the
> given
> + /// token the current token.
> + void UnconsumeToken(Token &Consumed) {
> + Token Next = Tok;
> + PP.EnterToken(Consumed);
> + ConsumeToken();
> + PP.EnterToken(Next);
> + }
> +
> /// ConsumeAnyToken - Dispatch to the right Consume* method based on
the
> /// current token type. This should only be used in cases where the
type
> of
> /// the token really isn't known, e.g. in error recovery.
> @@ -1396,6 +1405,8 @@ private:
>
>
//===--------------------------------------------------------------------
> ===//
> // C++ Expressions
> + ExprResult tryParseCXXIdExpression(CXXScopeSpec &SS, bool
> isAddressOfOperand,
> + Token &Replacement);
> ExprResult ParseCXXIdExpression(bool isAddressOfOperand = false);
>
> bool areTokensAdjacent(const Token &A, const Token &B);
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-
>
project/cfe/trunk/include/clang/Sema/Sema.h?rev=222464&r1=222463&r2=222464&v
> iew=diff
>
============================================================================
> ==
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Thu Nov 20 16:06:40 2014
> @@ -3463,7 +3463,7 @@ public:
> Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
> UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand,
> std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr,
> - bool IsInlineAsmIdentifier = false);
> + bool IsInlineAsmIdentifier = false, Token *KeywordReplacement =
> nullptr);
>
> void DecomposeUnqualifiedId(const UnqualifiedId &Id,
> TemplateArgumentListInfo &Buffer,
> @@ -3474,7 +3474,7 @@ public:
> DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
> std::unique_ptr<CorrectionCandidateCallback> CCC,
> TemplateArgumentListInfo *ExplicitTemplateArgs =
> nullptr,
> - ArrayRef<Expr *> Args = None);
> + ArrayRef<Expr *> Args = None, TypoExpr **Out =
> nullptr);
>
> ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S,
> IdentifierInfo *II,
>
> Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
> URL: http://llvm.org/viewvc/llvm-
>
project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=222464&r1=222463&r
> 2=222464&view=diff
>
============================================================================
> ==
> --- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Thu Nov 20 16:06:40 2014
> @@ -336,6 +336,7 @@ void Parser::ParseLexedMethodDeclaration
> DefArgResult = ParseBraceInitializer();
> } else
> DefArgResult = ParseAssignmentExpression();
> + DefArgResult = Actions.CorrectDelayedTyposInExpr(DefArgResult);
> if (DefArgResult.isInvalid())
> Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param,
> EqualLoc);
>
> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
> URL: http://llvm.org/viewvc/llvm-
>
project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=222464&r1=222463&r2=222464&vie
> w=diff
>
============================================================================
> ==
> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Nov 20 16:06:40 2014
> @@ -302,7 +302,8 @@ unsigned Parser::ParseAttributeArgsCommo
> Unevaluated.reset(
> new EnterExpressionEvaluationContext(Actions,
> Sema::Unevaluated));
>
> - ExprResult ArgExpr(ParseAssignmentExpression());
> + ExprResult ArgExpr(
> +
Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()));
> if (ArgExpr.isInvalid()) {
> SkipUntil(tok::r_paren, StopAtSemi);
> return 0;
> @@ -5566,6 +5567,7 @@ void Parser::ParseParameterDeclarationCl
> DefArgResult = ParseBraceInitializer();
> } else
> DefArgResult = ParseAssignmentExpression();
> + DefArgResult = Actions.CorrectDelayedTyposInExpr(DefArgResult);
> if (DefArgResult.isInvalid()) {
> Actions.ActOnParamDefaultArgumentError(Param, EqualLoc);
> SkipUntil(tok::comma, tok::r_paren, StopAtSemi |
> StopBeforeMatch);
>
> Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-
>
project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=222464&r1=222463&r2=222464&
> view=diff
>
============================================================================
> ==
> --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Nov 20 16:06:40 2014
> @@ -796,7 +796,7 @@ SourceLocation Parser::ParseDecltypeSpec
> // The operand of the decltype specifier is an unevaluated
operand.
> EnterExpressionEvaluationContext Unevaluated(Actions,
> Sema::Unevaluated,
>
> nullptr,/*IsDecltype=*/true);
> - Result = ParseExpression();
> + Result = Actions.CorrectDelayedTyposInExpr(ParseExpression());
> if (Result.isInvalid()) {
> DS.SetTypeSpecError();
> if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) {
>
> Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
> URL: http://llvm.org/viewvc/llvm-
>
project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=222464&r1=222463&r2=222464&vie
> w=diff
>
============================================================================
> ==
> --- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseExpr.cpp Thu Nov 20 16:06:40 2014
> @@ -277,6 +277,7 @@ Parser::ParseRHSOfBinaryExpression(ExprR
> // 'logical-OR-expression' as we might expect.
> TernaryMiddle = ParseExpression();
> if (TernaryMiddle.isInvalid()) {
> + Actions.CorrectDelayedTyposInExpr(LHS);
> LHS = ExprError();
> TernaryMiddle = nullptr;
> }
> @@ -345,9 +346,11 @@ Parser::ParseRHSOfBinaryExpression(ExprR
> else
> RHS = ParseCastExpression(false);
>
> - if (RHS.isInvalid())
> + if (RHS.isInvalid()) {
> + Actions.CorrectDelayedTyposInExpr(LHS);
> LHS = ExprError();
> -
> + }
> +
> // Remember the precedence of this operator and get the precedence of
> the
> // operator immediately to the right of the RHS.
> prec::Level ThisPrec = NextTokPrec;
> @@ -376,8 +379,10 @@ Parser::ParseRHSOfBinaryExpression(ExprR
> static_cast<prec::Level>(ThisPrec +
> !isRightAssoc));
> RHSIsInitList = false;
>
> - if (RHS.isInvalid())
> + if (RHS.isInvalid()) {
> + Actions.CorrectDelayedTyposInExpr(LHS);
> LHS = ExprError();
> + }
>
> NextTokPrec = getBinOpPrecedence(Tok.getKind(),
> GreaterThanIsOperator,
> getLangOpts().CPlusPlus11);
> @@ -413,7 +418,9 @@ Parser::ParseRHSOfBinaryExpression(ExprR
> LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
> LHS.get(), TernaryMiddle.get(),
> RHS.get());
> - }
> + } else
> + // Ensure potential typos in the RHS aren't left undiagnosed.
> + Actions.CorrectDelayedTyposInExpr(RHS);
> }
> }
>
> @@ -441,7 +448,7 @@ class CastExpressionIdValidator : public
> public:
> CastExpressionIdValidator(bool AllowTypes, bool AllowNonTypes)
> : AllowNonTypes(AllowNonTypes) {
> - WantTypeSpecifiers = AllowTypes;
> + WantTypeSpecifiers = WantFunctionLikeCasts = AllowTypes;
> }
>
> bool ValidateCandidate(const TypoCorrection &candidate) override {
> @@ -899,13 +906,20 @@ ExprResult Parser::ParseCastExpression(b
> UnqualifiedId Name;
> CXXScopeSpec ScopeSpec;
> SourceLocation TemplateKWLoc;
> + Token Replacement;
> auto Validator = llvm::make_unique<CastExpressionIdValidator>(
> isTypeCast != NotTypeCast, isTypeCast != IsTypeCast);
> Validator->IsAddressOfOperand = isAddressOfOperand;
> Name.setIdentifier(&II, ILoc);
> - Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec,
> TemplateKWLoc,
> - Name, Tok.is(tok::l_paren),
> - isAddressOfOperand,
> std::move(Validator));
> + Res = Actions.ActOnIdExpression(
> + getCurScope(), ScopeSpec, TemplateKWLoc, Name,
> Tok.is(tok::l_paren),
> + isAddressOfOperand, std::move(Validator),
> + /*IsInlineAsmIdentifier=*/false, &Replacement);
> + if (!Res.isInvalid() && !Res.get()) {
> + UnconsumeToken(Replacement);
> + return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
> + NotCastExpr, isTypeCast);
> + }
> break;
> }
> case tok::char_constant: // constant: character-constant
>
> Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
> URL: http://llvm.org/viewvc/llvm-
>
project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=222464&r1=222463&r2=222464&
> view=diff
>
============================================================================
> ==
> --- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu Nov 20 16:06:40 2014
> @@ -567,6 +567,28 @@ bool Parser::ParseOptionalCXXScopeSpecif
> return false;
> }
>
> +ExprResult Parser::tryParseCXXIdExpression(CXXScopeSpec &SS, bool
> isAddressOfOperand,
> + Token &Replacement) {
> + SourceLocation TemplateKWLoc;
> + UnqualifiedId Name;
> + if (ParseUnqualifiedId(SS,
> + /*EnteringContext=*/false,
> + /*AllowDestructorName=*/false,
> + /*AllowConstructorName=*/false,
> + /*ObjectType=*/ParsedType(), TemplateKWLoc,
Name))
> + return ExprError();
> +
> + // This is only the direct operand of an & operator if it is not
> + // followed by a postfix-expression suffix.
> + if (isAddressOfOperand && isPostfixExpressionSuffixStart())
> + isAddressOfOperand = false;
> +
> + return Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc,
Name,
> + Tok.is(tok::l_paren),
> isAddressOfOperand,
> + nullptr,
> /*IsInlineAsmIdentifier=*/false,
> + &Replacement);
> +}
> +
> /// ParseCXXIdExpression - Handle id-expression.
> ///
> /// id-expression:
> @@ -617,24 +639,17 @@ ExprResult Parser::ParseCXXIdExpression(
> CXXScopeSpec SS;
> ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
> /*EnteringContext=*/false);
>
> - SourceLocation TemplateKWLoc;
> - UnqualifiedId Name;
> - if (ParseUnqualifiedId(SS,
> - /*EnteringContext=*/false,
> - /*AllowDestructorName=*/false,
> - /*AllowConstructorName=*/false,
> - /*ObjectType=*/ ParsedType(),
> - TemplateKWLoc,
> - Name))
> - return ExprError();
> -
> - // This is only the direct operand of an & operator if it is not
> - // followed by a postfix-expression suffix.
> - if (isAddressOfOperand && isPostfixExpressionSuffixStart())
> - isAddressOfOperand = false;
> -
> - return Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc,
Name,
> - Tok.is(tok::l_paren),
> isAddressOfOperand);
> + Token Replacement;
> + ExprResult Result = tryParseCXXIdExpression(SS, isAddressOfOperand,
> Replacement);
> + if (Result.isUnset()) {
> + // If the ExprResult is valid but null, then typo correction
suggested
> a
> + // keyword replacement that needs to be reparsed.
> + UnconsumeToken(Replacement);
> + Result = tryParseCXXIdExpression(SS, isAddressOfOperand,
Replacement);
> + }
> + assert(!Result.isUnset() && "Typo correction suggested a keyword
> replacement "
> + "for a previous keyword suggestion");
> + return Result;
> }
>
> /// ParseLambdaExpression - Parse a C++11 lambda expression.
>
> Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
> URL: http://llvm.org/viewvc/llvm-
>
project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=222464&r1=222463&r2=222464&vie
> w=diff
>
============================================================================
> ==
> --- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseObjc.cpp Thu Nov 20 16:06:40 2014
> @@ -2170,7 +2170,10 @@ bool Parser::ParseObjCXXMessageReceiver(
> if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) {
> // objc-receiver:
> // expression
> - ExprResult Receiver = ParseExpression();
> + // Make sure any typos in the receiver are corrected or diagnosed, so
> that
> + // proper recovery can happen. FIXME: Perhaps filter the corrected
expr
> to
> + // only the things that are valid ObjC receivers?
> + ExprResult Receiver =
> Actions.CorrectDelayedTyposInExpr(ParseExpression());
> if (Receiver.isInvalid())
> return true;
>
>
> Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
> URL: http://llvm.org/viewvc/llvm-
>
project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=222464&r1=222463&r2=222464&v
> iew=diff
>
============================================================================
> ==
> --- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Thu Nov 20 16:06:40 2014
> @@ -741,7 +741,8 @@ OMPClause *Parser::ParseOpenMPVarListCla
> if (MustHaveTail) {
> ColonLoc = Tok.getLocation();
> ConsumeToken();
> - ExprResult Tail = ParseAssignmentExpression();
> + ExprResult Tail =
> + Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
> if (Tail.isUsable())
> TailExpr = Tail.get();
> else
>
> Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
> URL: http://llvm.org/viewvc/llvm-
>
project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=222464&r1=222463&r2=222464&vie
> w=diff
>
============================================================================
> ==
> --- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseStmt.cpp Thu Nov 20 16:06:40 2014
> @@ -642,6 +642,11 @@ StmtResult Parser::ParseCaseStatement(bo
> ExprResult LHS;
> if (!MissingCase) {
> LHS = ParseConstantExpression();
> + if (!getLangOpts().CPlusPlus11) {
> + LHS = Actions.CorrectDelayedTyposInExpr(LHS, [this](class Expr
*E)
> {
> + return Actions.VerifyIntegerConstantExpression(E);
> + });
> + }
> if (LHS.isInvalid()) {
> // If constant-expression is parsed unsuccessfully, recover by
> skipping
> // current case statement (moving to the colon that ends it).
> @@ -1562,7 +1567,7 @@ StmtResult Parser::ParseForStatement(Sou
> }
> } else {
> ProhibitAttributes(attrs);
> - Value = ParseExpression();
> + Value = Actions.CorrectDelayedTyposInExpr(ParseExpression());
>
> ForEach = isTokIdentifier_in();
>
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-
>
project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=222464&r1=222463&r2=222464&view=
> diff
>
============================================================================
> ==
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Nov 20 16:06:40 2014
> @@ -1673,6 +1673,40 @@ Sema::DecomposeUnqualifiedId(const Unqua
> }
> }
>
> +static void emitEmptyLookupTypoDiagnostic(
> + const TypoCorrection &TC, Sema &SemaRef, const CXXScopeSpec &SS,
> + DeclarationName Typo, SourceLocation TypoLoc, ArrayRef<Expr *> Args,
> + unsigned DiagnosticID, unsigned DiagnosticSuggestID) {
> + DeclContext *Ctx =
> + SS.isEmpty() ? nullptr : SemaRef.computeDeclContext(SS, false);
> + if (!TC) {
> + // Emit a special diagnostic for failed member lookups.
> + // FIXME: computing the declaration context might fail here (?)
> + if (Ctx)
> + SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << Ctx
> + << SS.getRange();
> + else
> + SemaRef.Diag(TypoLoc, DiagnosticID) << Typo;
> + return;
> + }
> +
> + std::string CorrectedStr = TC.getAsString(SemaRef.getLangOpts());
> + bool DroppedSpecifier =
> + TC.WillReplaceSpecifier() && Typo.getAsString() == CorrectedStr;
> + unsigned NoteID =
> + (TC.getCorrectionDecl() &&
> isa<ImplicitParamDecl>(TC.getCorrectionDecl()))
> + ? diag::note_implicit_param_decl
> + : diag::note_previous_decl;
> + if (!Ctx)
> + SemaRef.diagnoseTypo(TC, SemaRef.PDiag(DiagnosticSuggestID) << Typo,
> + SemaRef.PDiag(NoteID));
> + else
> + SemaRef.diagnoseTypo(TC, SemaRef.PDiag(diag::err_no_member_suggest)
> + << Typo << Ctx << DroppedSpecifier
> + << SS.getRange(),
> + SemaRef.PDiag(NoteID));
> +}
> +
> /// Diagnose an empty lookup.
> ///
> /// \return false if new lookup candidates were found
> @@ -1680,7 +1714,7 @@ bool
> Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
> std::unique_ptr<CorrectionCandidateCallback>
CCC,
> TemplateArgumentListInfo *ExplicitTemplateArgs,
> - ArrayRef<Expr *> Args) {
> + ArrayRef<Expr *> Args, TypoExpr **Out) {
> DeclarationName Name = R.getLookupName();
>
> unsigned diagnostic = diag::err_undeclared_var_use;
> @@ -1797,8 +1831,22 @@ Sema::DiagnoseEmptyLookup(Scope *S, CXXS
>
> // We didn't find anything, so try to correct for a typo.
> TypoCorrection Corrected;
> - if (S && (Corrected = CorrectTypo(R.getLookupNameInfo(),
> R.getLookupKind(),
> - S, &SS, std::move(CCC),
> CTK_ErrorRecovery))) {
> + if (S && Out) {
> + SourceLocation TypoLoc = R.getNameLoc();
> + assert(!ExplicitTemplateArgs &&
> + "Diagnosing an empty lookup with explicit template args!");
> + *Out = CorrectTypoDelayed(
> + R.getLookupNameInfo(), R.getLookupKind(), S, &SS, std::move(CCC),
> + [=](const TypoCorrection &TC) {
> + emitEmptyLookupTypoDiagnostic(TC, *this, SS, Name, TypoLoc,
Args,
> + diagnostic, diagnostic_suggest);
> + },
> + nullptr, CTK_ErrorRecovery);
> + if (*Out)
> + return true;
> + } else if (S && (Corrected =
> + CorrectTypo(R.getLookupNameInfo(),
> R.getLookupKind(), S,
> + &SS, std::move(CCC),
> CTK_ErrorRecovery))) {
> std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
> bool DroppedSpecifier =
> Corrected.WillReplaceSpecifier() && Name.getAsString() ==
> CorrectedStr;
> @@ -1950,7 +1998,7 @@ Sema::ActOnIdExpression(Scope *S, CXXSco
> SourceLocation TemplateKWLoc, UnqualifiedId &Id,
> bool HasTrailingLParen, bool IsAddressOfOperand,
> std::unique_ptr<CorrectionCandidateCallback> CCC,
> - bool IsInlineAsmIdentifier) {
> + bool IsInlineAsmIdentifier, Token
> *KeywordReplacement) {
> assert(!(IsAddressOfOperand && HasTrailingLParen) &&
> "cannot be direct & operand and have a trailing lparen");
> if (SS.isInvalid())
> @@ -2062,13 +2110,43 @@ Sema::ActOnIdExpression(Scope *S, CXXSco
>
> // If this name wasn't predeclared and if this is not a function
> // call, diagnose the problem.
> - auto DefaultValidator =
> llvm::make_unique<CorrectionCandidateCallback>();
> + TypoExpr *TE = nullptr;
> + auto DefaultValidator =
llvm::make_unique<CorrectionCandidateCallback>(
> + II, SS.isValid() ? SS.getScopeRep() : nullptr);
> DefaultValidator->IsAddressOfOperand = IsAddressOfOperand;
> assert((!CCC || CCC->IsAddressOfOperand == IsAddressOfOperand) &&
> "Typo correction callback misconfigured");
> - if (DiagnoseEmptyLookup(S, SS, R,
> - CCC ? std::move(CCC) :
> std::move(DefaultValidator)))
> - return ExprError();
> + if (CCC) {
> + // Make sure the callback knows what the typo being diagnosed is.
> + CCC->setTypoName(II);
> + if (SS.isValid())
> + CCC->setTypoNNS(SS.getScopeRep());
> + }
> + if (DiagnoseEmptyLookup(
> + S, SS, R, CCC ? std::move(CCC) : std::move(DefaultValidator),
> + nullptr, None, getLangOpts().CPlusPlus ? &TE : nullptr)) {
> + if (TE && KeywordReplacement) {
> + auto &State = getTypoExprState(TE);
> + auto BestTC = State.Consumer->getNextCorrection();
> + if (BestTC.isKeyword()) {
> + auto *II = BestTC.getCorrectionAsIdentifierInfo();
> + if (State.DiagHandler)
> + State.DiagHandler(BestTC);
> + KeywordReplacement->startToken();
> + KeywordReplacement->setKind(II->getTokenID());
> + KeywordReplacement->setIdentifierInfo(II);
> + KeywordReplacement-
> >setLocation(BestTC.getCorrectionRange().getBegin());
> + // Clean up the state associated with the TypoExpr, since it
has
> + // now been diagnosed (without a call to
> CorrectDelayedTyposInExpr).
> + clearDelayedTypo(TE);
> + // Signal that a correction to a keyword was performed by
> returning a
> + // valid-but-null ExprResult.
> + return (Expr*)nullptr;
> + }
> + State.Consumer->resetCorrectionStream();
> + }
> + return TE ? TE : ExprError();
> + }
>
> assert(!R.empty() &&
> "DiagnoseEmptyLookup returned false but added no results");
> @@ -12450,6 +12528,8 @@ void Sema::UpdateMarkingForLValueToRValu
> }
>
> ExprResult Sema::ActOnConstantExpression(ExprResult Res) {
> + Res = CorrectDelayedTyposInExpr(Res);
> +
> if (!Res.isUsable())
> return Res;
>
>
> Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
> URL: http://llvm.org/viewvc/llvm-
>
project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=222464&r1=222463&r2=222464&view=
> diff
>
============================================================================
> ==
> --- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Nov 20 16:06:40 2014
> @@ -371,6 +371,23 @@ Sema::ActOnCaseStmt(SourceLocation CaseL
> return StmtError();
> }
>
> + ExprResult LHS =
> + CorrectDelayedTyposInExpr(LHSVal, [this](class Expr *E) {
> + if (!getLangOpts().CPlusPlus11)
> + return VerifyIntegerConstantExpression(E);
> + if (Expr *CondExpr =
> + getCurFunction()->SwitchStack.back()->getCond()) {
> + QualType CondType = CondExpr->getType();
> + llvm::APSInt TempVal;
> + return CheckConvertedConstantExpression(E, CondType, TempVal,
> + CCEK_CaseValue);
> + }
> + return ExprError();
> + });
> + if (LHS.isInvalid())
> + return StmtError();
> + LHSVal = LHS.get();
> +
> if (!getLangOpts().CPlusPlus11) {
> // C99 6.8.4.2p3: The expression shall be an integer constant.
> // However, GCC allows any evaluatable integer expression.
> @@ -388,7 +405,7 @@ Sema::ActOnCaseStmt(SourceLocation CaseL
> }
> }
>
> - auto LHS = ActOnFinishFullExpr(LHSVal, LHSVal->getExprLoc(), false,
> + LHS = ActOnFinishFullExpr(LHSVal, LHSVal->getExprLoc(), false,
> getLangOpts().CPlusPlus11);
> if (LHS.isInvalid())
> return StmtError();
>
> Modified: cfe/trunk/test/FixIt/fixit-unrecoverable.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-
> unrecoverable.cpp?rev=222464&r1=222463&r2=222464&view=diff
>
============================================================================
> ==
> --- cfe/trunk/test/FixIt/fixit-unrecoverable.cpp (original)
> +++ cfe/trunk/test/FixIt/fixit-unrecoverable.cpp Thu Nov 20 16:06:40 2014
> @@ -6,7 +6,5 @@
> // RUN: %clang_cc1 -fsyntax-only -verify %s
>
> float f(int y) {
> - return static_cst<float>(y); // expected-error{{use of undeclared
> identifier 'static_cst'; did you mean 'static_cast'?}} \
> - // expected-error{{for function-style cast or type construction}}
> + return static_cst<float>(y); // expected-error{{use of undeclared
> identifier 'static_cst'; did you mean 'static_cast'?}}
> }
> -
>
> Modified: cfe/trunk/test/SemaCXX/typo-correction.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/typo-
> correction.cpp?rev=222464&r1=222463&r2=222464&view=diff
>
============================================================================
> ==
> --- cfe/trunk/test/SemaCXX/typo-correction.cpp (original)
> +++ cfe/trunk/test/SemaCXX/typo-correction.cpp Thu Nov 20 16:06:40 2014
> @@ -209,11 +209,12 @@ namespace PR13051 {
> };
>
> void foo(); // expected-note{{'foo' declared here}}
> - void g(void(*)());
> - void g(bool(S<int>::*)() const);
> + void g(void(*)()); // expected-note{{candidate function not viable}}
> + void g(bool(S<int>::*)() const); // expected-note{{candidate function
not
> viable}}
>
> void test() {
> - g(&S<int>::tempalte f<int>); // expected-error{{did you mean
> 'template'?}}
> + g(&S<int>::tempalte f<int>); // expected-error{{did you mean
> 'template'?}} \
> + // expected-error{{no matching function
> for call to 'g'}}
> g(&S<int>::opeartor bool); // expected-error{{did you mean
> 'operator'?}}
> g(&S<int>::foo); // expected-error{{no member named 'foo' in
> 'PR13051::S<int>'; did you mean simply 'foo'?}}
> }
>
> Modified: cfe/trunk/test/SemaTemplate/crash-10438657.cpp
> URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/crash-
> 10438657.cpp?rev=222464&r1=222463&r2=222464&view=diff
>
============================================================================
> ==
> --- cfe/trunk/test/SemaTemplate/crash-10438657.cpp (original)
> +++ cfe/trunk/test/SemaTemplate/crash-10438657.cpp Thu Nov 20 16:06:40
2014
> @@ -1,6 +1,6 @@
> // RUN: not %clang_cc1 -fsyntax-only %s 2> %t
> // RUN: FileCheck %s < %t
> -// CHECK: 10 errors
> +// CHECK: 9 errors
> template<typename _CharT>
> class collate : public locale::facet {
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list