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