It should be fixed in r223177. On Tue, Dec 2, 2014 at 2:13 PM, Kaelyn Takata <[email protected]> wrote:
> Yeah I can investigate it. Looks like another situation where TypoExprs > (part of the delayed typo correction) are going undiagnosed but for which > there were no existing tests covering the associated code paths. Thanks for > coming up with a reduced test case! > > On Tue, Dec 2, 2014 at 8:16 AM, Peter Smith <[email protected]> wrote: > >> 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: [email protected] [mailto:cfe-commits- >> > [email protected]] On Behalf Of Kaelyn Takata >> > Sent: 20 November 2014 22:07 >> > To: [email protected] >> > 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 >> > [email protected] >> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >> >> >> >> >> >> _______________________________________________ >> cfe-commits mailing list >> [email protected] >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >> > >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
