r222464 - Wire up delayed typo correction to DiagnoseEmptyLookup and set up
Kaelyn Takata
rikka at google.com
Tue Dec 2 15:36:03 PST 2014
It should be fixed in r223177.
On Tue, Dec 2, 2014 at 2:13 PM, Kaelyn Takata <rikka at google.com> 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 <peter.smith at arm.com> 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: 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
>>
>>
>>
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20141202/9bce90b3/attachment.html>
More information about the cfe-commits
mailing list