diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp index 69f6df46c87ce..775278ccf694b 100644 --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -974,7 +974,7 @@ class Foo final {})cpp"; HI.Name = "abc"; HI.Kind = index::SymbolKind::Variable; HI.NamespaceScope = ""; - HI.Definition = "int abc = ()"; + HI.Definition = "int abc"; HI.Type = "int"; HI.AccessSpecifier = "public"; }}, diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b5e6cf088a4b1..7cb2af38669d3 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -622,6 +622,14 @@ Improvements to Clang's diagnostics - Improved the FixIts for unused lambda captures. +- Delayed typo correction was removed from the compiler; immediate typo + correction behavior remains the same. Delayed typo correction facilities were + fragile and unmaintained, and the removal closed the following issues: + #GH142457, #GH139913, #GH138850, #GH137867, #GH137860, #GH107840, #GH93308, + #GH69470, #GH59391, #GH58172, #GH46215, #GH45915, #GH45891, #GH44490, + #GH36703, #GH32903, #GH23312, #GH69874. + + Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 43c28c8bf649f..9fc23d30b733f 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -240,8 +240,7 @@ class Expr : public ValueStmt { return static_cast(getDependence() & ExprDependence::UnexpandedPack); } - /// Whether this expression contains subexpressions which had errors, e.g. a - /// TypoExpr. + /// Whether this expression contains subexpressions which had errors. bool containsErrors() const { return static_cast(getDependence() & ExprDependence::Error); } @@ -6965,36 +6964,6 @@ class AtomicExpr : public Expr { } }; -/// TypoExpr - Internal placeholder for expressions where typo correction -/// still needs to be performed and/or an error diagnostic emitted. -class TypoExpr : public Expr { - // The location for the typo name. - SourceLocation TypoLoc; - -public: - TypoExpr(QualType T, SourceLocation TypoLoc) - : Expr(TypoExprClass, T, VK_LValue, OK_Ordinary), TypoLoc(TypoLoc) { - assert(T->isDependentType() && "TypoExpr given a non-dependent type"); - setDependence(ExprDependence::TypeValueInstantiation | - ExprDependence::Error); - } - - child_range children() { - return child_range(child_iterator(), child_iterator()); - } - const_child_range children() const { - return const_child_range(const_child_iterator(), const_child_iterator()); - } - - SourceLocation getBeginLoc() const LLVM_READONLY { return TypoLoc; } - SourceLocation getEndLoc() const LLVM_READONLY { return TypoLoc; } - - static bool classof(const Stmt *T) { - return T->getStmtClass() == TypoExprClass; - } - -}; - /// This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', /// with a boolean differentiator. /// OpenMP 5.0 [2.1.5, Array Sections]. diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index b0f8ae621cf6d..5cb2f57edffe4 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2956,7 +2956,6 @@ DEF_TRAVERSE_STMT(CXXRewrittenBinaryOperator, { } }) DEF_TRAVERSE_STMT(OpaqueValueExpr, {}) -DEF_TRAVERSE_STMT(TypoExpr, {}) DEF_TRAVERSE_STMT(RecoveryExpr, {}) DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {}) diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index 9526fa5808aa5..c9c173f5c7469 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -202,7 +202,6 @@ def ShuffleVectorExpr : StmtNode; def ConvertVectorExpr : StmtNode; def BlockExpr : StmtNode; def OpaqueValueExpr : StmtNode; -def TypoExpr : StmtNode; def RecoveryExpr : StmtNode; def BuiltinBitCastExpr : StmtNode; def EmbedExpr : StmtNode; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 0b2fab4a45c96..5a3941556d9d0 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -4171,8 +4171,7 @@ class Parser : public CodeCompletionHandler { bool ParseExpressionList(SmallVectorImpl &Exprs, llvm::function_ref ExpressionStarts = llvm::function_ref(), - bool FailImmediatelyOnInvalidExpr = false, - bool EarlyTypoCorrection = false); + bool FailImmediatelyOnInvalidExpr = false); /// ParseSimpleExpressionList - A simple comma-separated list of expressions, /// used for misc language extensions. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 0dad07e55a820..29452bb37260d 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -6713,10 +6713,6 @@ class Sema final : public SemaBase { /// this expression evaluation context. unsigned NumCleanupObjects; - /// The number of typos encountered during this expression evaluation - /// context (i.e. the number of TypoExprs created). - unsigned NumTypos; - MaybeODRUseExprSet SavedMaybeODRUseExprs; /// The lambdas that are present within this context, if it @@ -6813,7 +6809,7 @@ class Sema final : public SemaBase { Decl *ManglingContextDecl, ExpressionKind ExprContext) : Context(Context), ParentCleanup(ParentCleanup), - NumCleanupObjects(NumCleanupObjects), NumTypos(0), + NumCleanupObjects(NumCleanupObjects), ManglingContextDecl(ManglingContextDecl), ExprContext(ExprContext), InDiscardedStatement(false), InImmediateFunctionContext(false), InImmediateEscalatingFunctionContext(false) {} @@ -7146,8 +7142,7 @@ class Sema final : public SemaBase { CorrectionCandidateCallback &CCC, TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr, ArrayRef Args = {}, - DeclContext *LookupCtx = nullptr, - TypoExpr **Out = nullptr); + DeclContext *LookupCtx = nullptr); /// If \p D cannot be odr-used in the current expression evaluation context, /// return a reason explaining why. Otherwise, return NOUR_None. @@ -8748,40 +8743,6 @@ class Sema final : public SemaBase { ExprResult CheckUnevaluatedOperand(Expr *E); - /// Process any TypoExprs in the given Expr and its children, - /// generating diagnostics as appropriate and returning a new Expr if there - /// were typos that were all successfully corrected and ExprError if one or - /// more typos could not be corrected. - /// - /// \param E The Expr to check for TypoExprs. - /// - /// \param InitDecl A VarDecl to avoid because the Expr being corrected is its - /// initializer. - /// - /// \param RecoverUncorrectedTypos If true, when typo correction fails, it - /// will rebuild the given Expr with all TypoExprs degraded to RecoveryExprs. - /// - /// \param Filter A function applied to a newly rebuilt Expr to determine if - /// it is an acceptable/usable result from a single combination of typo - /// corrections. As long as the filter returns ExprError, different - /// combinations of corrections will be tried until all are exhausted. - ExprResult CorrectDelayedTyposInExpr( - Expr *E, VarDecl *InitDecl = nullptr, - bool RecoverUncorrectedTypos = false, - llvm::function_ref Filter = - [](Expr *E) -> ExprResult { return E; }); - - ExprResult CorrectDelayedTyposInExpr( - ExprResult ER, VarDecl *InitDecl = nullptr, - bool RecoverUncorrectedTypos = false, - llvm::function_ref Filter = - [](Expr *E) -> ExprResult { return E; }) { - return ER.isInvalid() - ? ER - : CorrectDelayedTyposInExpr(ER.get(), InitDecl, - RecoverUncorrectedTypos, Filter); - } - IfExistsResult CheckMicrosoftIfExistsSymbol(Scope *S, CXXScopeSpec &SS, const DeclarationNameInfo &TargetNameInfo); @@ -9283,12 +9244,6 @@ class Sema final : public SemaBase { /// for C++ records. llvm::FoldingSet SpecialMemberCache; - /// Holds TypoExprs that are created from `createDelayedTypo`. This is used by - /// `TransformTypos` in order to keep track of any TypoExprs that are created - /// recursively during typo correction and wipe them away if the correction - /// fails. - llvm::SmallVector TypoExprs; - enum class AcceptableKind { Visible, Reachable }; // Members have to be NamespaceDecl* or TranslationUnitDecl*. @@ -9376,10 +9331,6 @@ class Sema final : public SemaBase { bool VolatileArg, bool RValueThis, bool ConstThis, bool VolatileThis); - typedef std::function TypoDiagnosticGenerator; - typedef std::function - TypoRecoveryCallback; - RedeclarationKind forRedeclarationInCurContext() const; /// Look up a name, looking for a single declaration. Return @@ -9733,51 +9684,6 @@ class Sema final : public SemaBase { const ObjCObjectPointerType *OPT = nullptr, bool RecordFailure = true); - /// Try to "correct" a typo in the source code by finding - /// visible declarations whose names are similar to the name that was - /// present in the source code. - /// - /// \param TypoName the \c DeclarationNameInfo structure that contains - /// the name that was present in the source code along with its location. - /// - /// \param LookupKind the name-lookup criteria used to search for the name. - /// - /// \param S the scope in which name lookup occurs. - /// - /// \param SS the nested-name-specifier that precedes the name we're - /// looking for, if present. - /// - /// \param CCC A CorrectionCandidateCallback object that provides further - /// validation of typo correction candidates. It also provides flags for - /// determining the set of keywords permitted. - /// - /// \param TDG A TypoDiagnosticGenerator functor that will be used to print - /// diagnostics when the actual typo correction is attempted. - /// - /// \param TRC A TypoRecoveryCallback functor that will be used to build an - /// Expr from a typo correction candidate. - /// - /// \param MemberContext if non-NULL, the context in which to look for - /// a member access expression. - /// - /// \param EnteringContext whether we're entering the context described by - /// the nested-name-specifier SS. - /// - /// \param OPT when non-NULL, the search for visible declarations will - /// also walk the protocols in the qualified interfaces of \p OPT. - /// - /// \returns a new \c TypoExpr that will later be replaced in the AST with an - /// Expr representing the result of performing typo correction, or nullptr if - /// typo correction is not possible. If nullptr is returned, no diagnostics - /// will be emitted and it is the responsibility of the caller to emit any - /// that are needed. - TypoExpr *CorrectTypoDelayed( - const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, - Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, - TypoDiagnosticGenerator TDG, TypoRecoveryCallback TRC, - CorrectTypoKind Mode, DeclContext *MemberContext = nullptr, - bool EnteringContext = false, const ObjCObjectPointerType *OPT = nullptr); - /// Kinds of missing import. Note, the values of these enumerators correspond /// to %select values in diagnostics. enum class MissingImportKind { @@ -9796,20 +9702,6 @@ class Sema final : public SemaBase { SourceLocation DeclLoc, ArrayRef Modules, MissingImportKind MIK, bool Recover); - struct TypoExprState { - std::unique_ptr Consumer; - TypoDiagnosticGenerator DiagHandler; - TypoRecoveryCallback RecoveryHandler; - TypoExprState(); - TypoExprState(TypoExprState &&other) noexcept; - TypoExprState &operator=(TypoExprState &&other) noexcept; - }; - - const TypoExprState &getTypoExprState(TypoExpr *TE) const; - - /// Clears the state of the given TypoExpr. - void clearDelayedTypo(TypoExpr *TE); - /// Called on #pragma clang __debug dump II void ActOnPragmaDump(Scope *S, SourceLocation Loc, IdentifierInfo *II); @@ -9832,23 +9724,15 @@ class Sema final : public SemaBase { /// Determine if we could use all the declarations in the module. bool isUsableModule(const Module *M); - /// Helper for CorrectTypo and CorrectTypoDelayed used to create and - /// populate a new TypoCorrectionConsumer. Returns nullptr if typo correction - /// should be skipped entirely. + /// Helper for CorrectTypo used to create and populate a new + /// TypoCorrectionConsumer. Returns nullptr if typo correction should be + /// skipped entirely. std::unique_ptr makeTypoCorrectionConsumer( const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, DeclContext *MemberContext, bool EnteringContext, const ObjCObjectPointerType *OPT, bool ErrorRecovery); - /// The set of unhandled TypoExprs and their associated state. - llvm::MapVector DelayedTypos; - - /// Creates a new TypoExpr AST node. - TypoExpr *createDelayedTypo(std::unique_ptr TCC, - TypoDiagnosticGenerator TDG, - TypoRecoveryCallback TRC, SourceLocation TypoLoc); - /// Cache for module units which is usable for current module. llvm::DenseSet UsableModuleUnitsCache; diff --git a/clang/include/clang/Sema/SemaInternal.h b/clang/include/clang/Sema/SemaInternal.h index 95874077050a9..4d0da1102bb59 100644 --- a/clang/include/clang/Sema/SemaInternal.h +++ b/clang/include/clang/Sema/SemaInternal.h @@ -314,20 +314,6 @@ class TypoCorrectionConsumer : public VisibleDeclConsumer { bool SearchNamespaces; }; -inline Sema::TypoExprState::TypoExprState() {} - -inline Sema::TypoExprState::TypoExprState(TypoExprState &&other) noexcept { - *this = std::move(other); -} - -inline Sema::TypoExprState &Sema::TypoExprState:: -operator=(Sema::TypoExprState &&other) noexcept { - Consumer = std::move(other.Consumer); - DiagHandler = std::move(other.DiagHandler); - RecoveryHandler = std::move(other.RecoveryHandler); - return *this; -} - } // end namespace clang #endif diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 17d2cb4a30f30..c3722c65abf6e 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -3611,7 +3611,6 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, case PackExpansionExprClass: case SubstNonTypeTemplateParmPackExprClass: case FunctionParmPackExprClass: - case TypoExprClass: case RecoveryExprClass: case CXXFoldExprClass: // Make a conservative assumption for dependent nodes. diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 3f37d06cc8f3a..ad66335138a42 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -129,7 +129,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { // FIXME: Is this wise? Should they get their own kind? case Expr::UnresolvedLookupExprClass: case Expr::UnresolvedMemberExprClass: - case Expr::TypoExprClass: case Expr::DependentCoawaitExprClass: case Expr::CXXDependentScopeMemberExprClass: case Expr::DependentScopeDeclRefExprClass: diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 27ea55e981446..f1580255a462a 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -17327,7 +17327,6 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { case Expr::CXXDeleteExprClass: case Expr::CXXPseudoDestructorExprClass: case Expr::UnresolvedLookupExprClass: - case Expr::TypoExprClass: case Expr::RecoveryExprClass: case Expr::DependentScopeDeclRefExprClass: case Expr::CXXConstructExprClass: diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index ecf5be220439b..487933a748ab8 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4994,7 +4994,6 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity, case Expr::ParenListExprClass: case Expr::MSPropertyRefExprClass: case Expr::MSPropertySubscriptExprClass: - case Expr::TypoExprClass: // This should no longer exist in the AST by now. case Expr::RecoveryExprClass: case Expr::ArraySectionExprClass: case Expr::OMPArrayShapingExprClass: diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 13c3bc0387890..28317911d825b 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -2914,11 +2914,6 @@ void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) { PrintExpr(Node->getSourceExpr()); } -void StmtPrinter::VisitTypoExpr(TypoExpr *Node) { - // TODO: Print something reasonable for a TypoExpr, if necessary. - llvm_unreachable("Cannot print TypoExpr nodes"); -} - void StmtPrinter::VisitRecoveryExpr(RecoveryExpr *Node) { OS << "("; const char *Sep = ""; diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index f7d1655f67ed1..c666d966a6e58 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2361,10 +2361,6 @@ void StmtProfiler::VisitOpaqueValueExpr(const OpaqueValueExpr *E) { VisitExpr(E); } -void StmtProfiler::VisitTypoExpr(const TypoExpr *E) { - VisitExpr(E); -} - void StmtProfiler::VisitSourceLocExpr(const SourceLocExpr *E) { VisitExpr(E); } diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index e215c64cccd11..9a010fb5f3427 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -422,7 +422,6 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { DefArgResult = ParseBraceInitializer(); } else DefArgResult = ParseAssignmentExpression(); - DefArgResult = Actions.CorrectDelayedTyposInExpr(DefArgResult, Param); if (DefArgResult.isInvalid()) { Actions.ActOnParamDefaultArgumentError(Param, EqualLoc, /*DefaultArg=*/nullptr); diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index f469e466e4634..647ee34efcabc 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -436,7 +436,6 @@ bool Parser::ParseAttributeArgumentList( } else { Expr = ParseAssignmentExpression(); } - Expr = Actions.CorrectDelayedTyposInExpr(Expr); if (Tok.is(tok::ellipsis)) Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken()); @@ -472,15 +471,6 @@ bool Parser::ParseAttributeArgumentList( Arg++; } - if (SawError) { - // Ensure typos get diagnosed when errors were encountered while parsing the - // expression list. - for (auto &E : Exprs) { - ExprResult Expr = Actions.CorrectDelayedTyposInExpr(E); - if (Expr.isUsable()) - E = Expr.get(); - } - } return SawError; } @@ -565,9 +555,7 @@ unsigned Parser::ParseAttributeArgsCommon( nullptr, Sema::ExpressionEvaluationContextRecord::EK_AttrArgument); - ExprResult ArgExpr( - Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression())); - + ExprResult ArgExpr = ParseAssignmentExpression(); if (ArgExpr.isInvalid()) { SkipUntil(tok::r_paren, StopAtSemi); return 0; @@ -3212,9 +3200,7 @@ void Parser::ParseBoundsAttribute(IdentifierInfo &AttrName, Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, nullptr, ExpressionKind::EK_AttrArgument); - ExprResult ArgExpr( - Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression())); - + ExprResult ArgExpr = ParseAssignmentExpression(); if (ArgExpr.isInvalid()) { Parens.skipToEnd(); return; @@ -6890,8 +6876,8 @@ void Parser::ParseDirectDeclarator(Declarator &D) { // void (f()) requires true; Diag(Tok, diag::err_requires_clause_inside_parens); ConsumeToken(); - ExprResult TrailingRequiresClause = Actions.CorrectDelayedTyposInExpr( - ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true)); + ExprResult TrailingRequiresClause = + ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true); if (TrailingRequiresClause.isUsable() && D.isFunctionDeclarator() && !D.hasTrailingRequiresClause()) // We're already ill-formed if we got here but we'll accept it anyway. @@ -7538,8 +7524,7 @@ void Parser::ParseParameterDeclarationClause( Diag(Tok, diag::err_requires_clause_on_declarator_not_declaring_a_function); ConsumeToken(); - Actions.CorrectDelayedTyposInExpr( - ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true)); + ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true); } // Remember this parsed parameter in ParamInfo. @@ -7653,7 +7638,6 @@ void Parser::ParseParameterDeclarationClause( } DefArgResult = ParseAssignmentExpression(); } - DefArgResult = Actions.CorrectDelayedTyposInExpr(DefArgResult); if (DefArgResult.isInvalid()) { Actions.ActOnParamDefaultArgumentError(Param, EqualLoc, /*DefaultArg=*/nullptr); @@ -7799,8 +7783,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) { } else { EnterExpressionEvaluationContext Unevaluated( Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); - NumElements = - Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); + NumElements = ParseAssignmentExpression(); } } else { if (StaticLoc.isValid()) { @@ -7937,8 +7920,8 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) { bool isCastExpr; ParsedType CastTy; SourceRange CastRange; - ExprResult Operand = Actions.CorrectDelayedTyposInExpr( - ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange)); + ExprResult Operand = + ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange); if (HasParens) DS.setTypeArgumentRange(CastRange); diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 0b5f56fea0b14..5f34370aeeb2d 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1071,10 +1071,7 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) { EnterExpressionEvaluationContext Unevaluated( Actions, Sema::ExpressionEvaluationContext::Unevaluated, nullptr, Sema::ExpressionEvaluationContextRecord::EK_Decltype); - Result = Actions.CorrectDelayedTyposInExpr( - ParseExpression(), /*InitDecl=*/nullptr, - /*RecoverUncorrectedTypos=*/false, - [](Expr *E) { return E->hasPlaceholderType() ? ExprError() : E; }); + Result = ParseExpression(); if (Result.isInvalid()) { DS.SetTypeSpecError(); if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) { @@ -4465,8 +4462,7 @@ bool Parser::ParseCXXAssumeAttributeArg( Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated); TentativeParsingAction TPA(*this); - ExprResult Res( - Actions.CorrectDelayedTyposInExpr(ParseConditionalExpression())); + ExprResult Res = ParseConditionalExpression(); if (Res.isInvalid()) { TPA.Commit(); SkipUntil(tok::r_paren, tok::r_square, StopAtSemi | StopBeforeMatch); diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 951a157305ddc..a27a44455b621 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -183,7 +183,6 @@ ExprResult Parser::ParseConstraintExpression() { ExprResult LHS(ParseCastExpression(CastParseKind::AnyCastExpr)); ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::LogicalOr)); if (Res.isUsable() && !Actions.CheckConstraintExpression(Res.get())) { - Actions.CorrectDelayedTyposInExpr(Res); return ExprError(); } return Res; @@ -244,7 +243,6 @@ Parser::ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause) { // the rest of the addition expression). Try to parse the rest of it here. if (PossibleNonPrimary) E = RecoverFromNonPrimary(E, /*Note=*/!IsConstraintExpr); - Actions.CorrectDelayedTyposInExpr(E); return ExprError(); } return E; @@ -256,14 +254,11 @@ Parser::ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause) { SourceLocation LogicalAndLoc = ConsumeToken(); ExprResult RHS = ParsePrimary(); if (RHS.isInvalid()) { - Actions.CorrectDelayedTyposInExpr(LHS); return ExprError(); } ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalAndLoc, tok::ampamp, LHS.get(), RHS.get()); if (!Op.isUsable()) { - Actions.CorrectDelayedTyposInExpr(RHS); - Actions.CorrectDelayedTyposInExpr(LHS); return ExprError(); } LHS = Op; @@ -281,14 +276,11 @@ Parser::ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause) { ExprResult RHS = ParseConstraintLogicalAndExpression(IsTrailingRequiresClause); if (!RHS.isUsable()) { - Actions.CorrectDelayedTyposInExpr(LHS); return ExprError(); } ExprResult Op = Actions.ActOnBinOp(getCurScope(), LogicalOrLoc, tok::pipepipe, LHS.get(), RHS.get()); if (!Op.isUsable()) { - Actions.CorrectDelayedTyposInExpr(RHS); - Actions.CorrectDelayedTyposInExpr(LHS); return ExprError(); } LHS = Op; @@ -408,7 +400,6 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { } if (TernaryMiddle.isInvalid()) { - Actions.CorrectDelayedTyposInExpr(LHS); LHS = ExprError(); TernaryMiddle = nullptr; } @@ -466,11 +457,6 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { RHS = ParseCastExpression(CastParseKind::AnyCastExpr); if (RHS.isInvalid()) { - // FIXME: Errors generated by the delayed typo correction should be - // printed before errors from parsing the RHS, not after. - Actions.CorrectDelayedTyposInExpr(LHS); - if (TernaryMiddle.isUsable()) - TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle); LHS = ExprError(); } @@ -503,11 +489,6 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { RHSIsInitList = false; if (RHS.isInvalid()) { - // FIXME: Errors generated by the delayed typo correction should be - // printed before errors from ParseRHSOfBinaryExpression, not after. - Actions.CorrectDelayedTyposInExpr(LHS); - if (TernaryMiddle.isUsable()) - TernaryMiddle = Actions.CorrectDelayedTyposInExpr(TernaryMiddle); LHS = ExprError(); } @@ -571,17 +552,6 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { LHS = CondOp; } - // In this case, ActOnBinOp or ActOnConditionalOp performed the - // CorrectDelayedTyposInExpr check. - if (!getLangOpts().CPlusPlus) - continue; - } - - // Ensure potential typos aren't left undiagnosed. - if (LHS.isInvalid()) { - Actions.CorrectDelayedTyposInExpr(OrigLHS); - Actions.CorrectDelayedTyposInExpr(TernaryMiddle); - Actions.CorrectDelayedTyposInExpr(RHS); } } } @@ -1711,7 +1681,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { // Reject array indices starting with a lambda-expression. '[[' is // reserved for attributes. if (CheckProhibitedCXX11Attribute()) { - (void)Actions.CorrectDelayedTyposInExpr(LHS); return ExprError(); } BalancedDelimiterTracker T(*this, tok::l_square); @@ -1737,8 +1706,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { } else { Idx = ParseExpression(); // May be a comma expression } - LHS = Actions.CorrectDelayedTyposInExpr(LHS); - Idx = Actions.CorrectDelayedTyposInExpr(Idx); if (Idx.isInvalid()) { HasError = true; } else { @@ -1746,7 +1713,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { } } else if (Tok.isNot(tok::r_square)) { if (ParseExpressionList(ArgExprs)) { - LHS = Actions.CorrectDelayedTyposInExpr(LHS); HasError = true; } } @@ -1762,7 +1728,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { // Consume ':' ColonLocFirst = ConsumeToken(); if (Tok.isNot(tok::r_square)) - Length = Actions.CorrectDelayedTyposInExpr(ParseExpression()); + Length = ParseExpression(); } } else if (ArgExprs.size() <= 1 && getLangOpts().OpenMP) { ColonProtectionRAIIObject RAII(*this); @@ -1773,7 +1739,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { (getLangOpts().OpenMP < 50 || ((Tok.isNot(tok::colon) && getLangOpts().OpenMP >= 50)))) { Length = ParseExpression(); - Length = Actions.CorrectDelayedTyposInExpr(Length); } } if (getLangOpts().OpenMP >= 50 && @@ -1789,8 +1754,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { } SourceLocation RLoc = Tok.getLocation(); - LHS = Actions.CorrectDelayedTyposInExpr(LHS); - if (!LHS.isInvalid() && !HasError && !Length.isInvalid() && !Stride.isInvalid() && Tok.is(tok::r_square)) { if (ColonLocFirst.isValid() || ColonLocSecond.isValid()) { @@ -1838,7 +1801,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { SourceLocation OpenLoc = ConsumeToken(); if (ParseSimpleExpressionList(ExecConfigExprs)) { - (void)Actions.CorrectDelayedTyposInExpr(LHS); LHS = ExprError(); } @@ -1889,16 +1851,12 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp); }))) { - (void)Actions.CorrectDelayedTyposInExpr(LHS); // If we got an error when parsing expression list, we don't call // the CodeCompleteCall handler inside the parser. So call it here // to make sure we get overload suggestions even when we are in the // middle of a parameter. if (PP.isCodeCompletionReached() && !CalledSignatureHelp) RunSignatureHelp(); - } else if (LHS.isInvalid()) { - for (auto &E : ArgExprs) - Actions.CorrectDelayedTyposInExpr(E); } } } @@ -1913,16 +1871,16 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { ArgExprs); SkipUntil(tok::r_paren, StopAtSemi); } else if (Tok.isNot(tok::r_paren)) { - bool HadDelayedTypo = false; - if (Actions.CorrectDelayedTyposInExpr(LHS).get() != LHS.get()) - HadDelayedTypo = true; + bool HadErrors = false; + if (LHS.get()->containsErrors()) + HadErrors = true; for (auto &E : ArgExprs) - if (Actions.CorrectDelayedTyposInExpr(E).get() != E) - HadDelayedTypo = true; - // If there were delayed typos in the LHS or ArgExprs, call SkipUntil - // instead of PT.consumeClose() to avoid emitting extra diagnostics for - // the unmatched l_paren. - if (HadDelayedTypo) + if (E->containsErrors()) + HadErrors = true; + // If there were errors in the LHS or ArgExprs, call SkipUntil instead + // of PT.consumeClose() to avoid emitting extra diagnostics for the + // unmatched l_paren. + if (HadErrors) SkipUntil(tok::r_paren, StopAtSemi); else PT.consumeClose(); @@ -2050,7 +2008,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { /*AllowConstructorName=*/ getLangOpts().MicrosoftExt && SS.isNotEmpty(), /*AllowDeductionGuide=*/false, &TemplateKWLoc, Name)) { - (void)Actions.CorrectDelayedTyposInExpr(LHS); LHS = ExprError(); } @@ -2921,8 +2878,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, do { BalancedDelimiterTracker TS(*this, tok::l_square); TS.consumeOpen(); - ExprResult NumElements = - Actions.CorrectDelayedTyposInExpr(ParseExpression()); + ExprResult NumElements = ParseExpression(); if (!NumElements.isUsable()) { ErrorFound = true; while (!SkipUntil(tok::r_square, tok::r_paren, @@ -2936,7 +2892,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, // Match the ')'. T.consumeClose(); RParenLoc = T.getCloseLocation(); - Result = Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); + Result = ParseAssignmentExpression(); if (ErrorFound) { Result = ExprError(); } else if (!Result.isInvalid()) { @@ -2948,12 +2904,6 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, InMessageExpressionRAIIObject InMessage(*this, false); Result = ParseExpression(TypeCastState::MaybeTypeCast); - if (!getLangOpts().CPlusPlus && Result.isUsable()) { - // Correct typos in non-C++ code earlier so that implicit-cast-like - // expressions are parsed correctly. - Result = Actions.CorrectDelayedTyposInExpr(Result); - } - if (ExprType >= ParenParseOption::FoldExpr && isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) { ExprType = ParenParseOption::FoldExpr; @@ -3057,8 +3007,7 @@ ExprResult Parser::ParseGenericSelectionExpression() { // not evaluated." EnterExpressionEvaluationContext Unevaluated( Actions, Sema::ExpressionEvaluationContext::Unevaluated); - ControllingExpr = - Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); + ControllingExpr = ParseAssignmentExpression(); if (ControllingExpr.isInvalid()) { SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); @@ -3104,8 +3053,7 @@ ExprResult Parser::ParseGenericSelectionExpression() { // FIXME: These expressions should be parsed in a potentially potentially // evaluated context. - ExprResult ER( - Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression())); + ExprResult ER = ParseAssignmentExpression(); if (ER.isInvalid()) { SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); @@ -3199,8 +3147,7 @@ void Parser::injectEmbedTokens() { bool Parser::ParseExpressionList(SmallVectorImpl &Exprs, llvm::function_ref ExpressionStarts, - bool FailImmediatelyOnInvalidExpr, - bool EarlyTypoCorrection) { + bool FailImmediatelyOnInvalidExpr) { bool SawError = false; while (true) { if (ExpressionStarts) @@ -3213,9 +3160,6 @@ bool Parser::ParseExpressionList(SmallVectorImpl &Exprs, } else Expr = ParseAssignmentExpression(); - if (EarlyTypoCorrection) - Expr = Actions.CorrectDelayedTyposInExpr(Expr); - if (Tok.is(tok::ellipsis)) Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken()); else if (Tok.is(tok::code_completion)) { @@ -3244,14 +3188,6 @@ bool Parser::ParseExpressionList(SmallVectorImpl &Exprs, ConsumeToken(); checkPotentialAngleBracketDelimiter(Comma); } - if (SawError) { - // Ensure typos get diagnosed when errors were encountered while parsing the - // expression list. - for (auto &E : Exprs) { - ExprResult Expr = Actions.CorrectDelayedTyposInExpr(E); - if (Expr.isUsable()) E = Expr.get(); - } - } return SawError; } diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index d95260829e4a0..6505f433dc1ba 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -972,8 +972,6 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, SourceLocation StartLoc = Tok.getLocation(); InMessageExpressionRAIIObject MaybeInMessageExpression(*this, true); Init = ParseInitializer(); - if (!Init.isInvalid()) - Init = Actions.CorrectDelayedTyposInExpr(Init.get()); if (Tok.getLocation() != StartLoc) { // Back out the lexing of the token after the initializer. @@ -1065,8 +1063,6 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, // enclosing the lambda-expression, rather than in the context of the // lambda-expression itself. ParsedType InitCaptureType; - if (Init.isUsable()) - Init = Actions.CorrectDelayedTyposInExpr(Init.get()); if (Init.isUsable()) { NonTentativeAction([&] { // Get the pointer and store it in an lvalue, so we can use it as an @@ -3202,8 +3198,7 @@ ExprResult Parser::ParseRequiresExpression() { // cv-qualifier-seq[opt] abstract-declarator[opt] BalancedDelimiterTracker ExprBraces(*this, tok::l_brace); ExprBraces.consumeOpen(); - ExprResult Expression = - Actions.CorrectDelayedTyposInExpr(ParseExpression()); + ExprResult Expression = ParseExpression(); if (!Expression.isUsable()) { ExprBraces.skipToEnd(); SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); @@ -3306,8 +3301,7 @@ ExprResult Parser::ParseRequiresExpression() { // C++ [expr.prim.req.nested] // nested-requirement: // 'requires' constraint-expression ';' - ExprResult ConstraintExpr = - Actions.CorrectDelayedTyposInExpr(ParseConstraintExpression()); + ExprResult ConstraintExpr = ParseConstraintExpression(); if (ConstraintExpr.isInvalid() || !ConstraintExpr.isUsable()) { SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); @@ -3373,8 +3367,7 @@ ExprResult Parser::ParseRequiresExpression() { // simple-requirement: // expression ';' SourceLocation StartLoc = Tok.getLocation(); - ExprResult Expression = - Actions.CorrectDelayedTyposInExpr(ParseExpression()); + ExprResult Expression = ParseExpression(); if (!Expression.isUsable()) { SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); break; diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp index df8372b995e55..a3be3744a9327 100644 --- a/clang/lib/Parse/ParseInit.cpp +++ b/clang/lib/Parse/ParseInit.cpp @@ -477,8 +477,6 @@ ExprResult Parser::ParseBraceInitializer() { if (Tok.is(tok::ellipsis)) SubElt = Actions.ActOnPackExpansion(SubElt.get(), ConsumeToken()); - SubElt = Actions.CorrectDelayedTyposInExpr(SubElt.get()); - // If we couldn't parse the subelement, bail out. if (SubElt.isUsable()) { InitExprs.push_back(SubElt.get()); diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 6afb7809d3cd2..8ef16a4d3808a 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -2629,10 +2629,7 @@ bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) { if (!Tok.isSimpleTypeSpecifier(getLangOpts())) { // objc-receiver: // expression - // 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()); + ExprResult Receiver = ParseExpression(); if (Receiver.isInvalid()) return true; @@ -2809,7 +2806,7 @@ ExprResult Parser::ParseObjCMessageExpression() { } // Otherwise, an arbitrary expression can be the receiver of a send. - ExprResult Res = Actions.CorrectDelayedTyposInExpr(ParseExpression()); + ExprResult Res = ParseExpression(); if (Res.isInvalid()) { SkipUntil(tok::r_square, StopAtSemi); return Res; @@ -2930,8 +2927,6 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, SourceLocation commaLoc = ConsumeToken(); // Eat the ','. /// Parse the expression after ',' ExprResult Res(ParseAssignmentExpression()); - if (Tok.is(tok::colon)) - Res = Actions.CorrectDelayedTyposInExpr(Res); if (Res.isInvalid()) { if (Tok.is(tok::colon)) { Diag(commaLoc, diag::note_extra_comma_message_arg) << @@ -3078,10 +3073,6 @@ ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) { return Res; } - Res = Actions.CorrectDelayedTyposInExpr(Res.get()); - if (Res.isInvalid()) - HasInvalidEltExpr = true; - // Parse the ellipsis that indicates a pack expansion. if (Tok.is(tok::ellipsis)) Res = Actions.ActOnPackExpansion(Res.get(), ConsumeToken()); @@ -3108,7 +3099,6 @@ ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) { ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) { SmallVector Elements; // dictionary elements. ConsumeBrace(); // consume the l_square. - bool HasInvalidEltExpr = false; while (Tok.isNot(tok::r_brace)) { // Parse the comma separated key : value expressions. ExprResult KeyExpr; @@ -3138,12 +3128,6 @@ ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) { return ValueExpr; } - // Check the key and value for possible typos - KeyExpr = Actions.CorrectDelayedTyposInExpr(KeyExpr.get()); - ValueExpr = Actions.CorrectDelayedTyposInExpr(ValueExpr.get()); - if (KeyExpr.isInvalid() || ValueExpr.isInvalid()) - HasInvalidEltExpr = true; - // Parse the ellipsis that designates this as a pack expansion. Do not // ActOnPackExpansion here, leave it to template instantiation time where // we can get better diagnostics. @@ -3163,9 +3147,6 @@ ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) { } SourceLocation EndLoc = ConsumeBrace(); - if (HasInvalidEltExpr) - return ExprError(); - // Create the ObjCDictionaryLiteral. return Actions.ObjC().BuildObjCDictionaryLiteral(SourceRange(AtLoc, EndLoc), Elements); diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp index ca4f878464c4f..f2849c4eac7cc 100644 --- a/clang/lib/Parse/ParseOpenACC.cpp +++ b/clang/lib/Parse/ParseOpenACC.cpp @@ -653,7 +653,7 @@ ExprResult Parser::ParseOpenACCConditionExpr() { // it does in an if/while/etc (See ParseCXXCondition), however as it was // written with Fortran/C in mind, we're going to assume it just means an // 'expression evaluating to boolean'. - ExprResult ER = getActions().CorrectDelayedTyposInExpr(ParseExpression()); + ExprResult ER = ParseExpression(); if (!ER.isUsable()) return ER; @@ -761,12 +761,6 @@ Parser::ParseOpenACCIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK, if (!ER.isUsable()) return {ER, OpenACCParseCanContinue::Cannot}; - // Parsing can continue after the initial assignment expression parsing, so - // even if there was a typo, we can continue. - ER = getActions().CorrectDelayedTyposInExpr(ER); - if (!ER.isUsable()) - return {ER, OpenACCParseCanContinue::Can}; - return {getActions().OpenACC().ActOnIntExpr(DK, CK, Loc, ER.get()), OpenACCParseCanContinue::Can}; } @@ -836,8 +830,7 @@ ExprResult Parser::ParseOpenACCSizeExpr(OpenACCClauseKind CK) { return getActions().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc); } - ExprResult SizeExpr = - getActions().CorrectDelayedTyposInExpr(ParseConstantExpression()); + ExprResult SizeExpr = ParseConstantExpression(); if (!SizeExpr.isUsable()) return SizeExpr; @@ -891,8 +884,7 @@ Parser::OpenACCGangArgRes Parser::ParseOpenACCGangArg(SourceLocation GangLoc) { ConsumeToken(); // Parse this as a const-expression, and we'll check its integer-ness/value // in CheckGangExpr. - ExprResult Res = - getActions().CorrectDelayedTyposInExpr(ParseConstantExpression()); + ExprResult Res = ParseConstantExpression(); return {OpenACCGangKind::Dim, Res}; } @@ -1089,8 +1081,7 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams( case OpenACCClauseKind::Collapse: { bool HasForce = tryParseAndConsumeSpecialTokenKind( *this, OpenACCSpecialTokenKind::Force, ClauseKind); - ExprResult LoopCount = - getActions().CorrectDelayedTyposInExpr(ParseConstantExpression()); + ExprResult LoopCount = ParseConstantExpression(); if (LoopCount.isInvalid()) { Parens.skipToEnd(); return OpenACCCanContinue(); @@ -1387,7 +1378,7 @@ ExprResult Parser::ParseOpenACCIDExpression() { /*isAddressOfOperand=*/false); } - return getActions().CorrectDelayedTyposInExpr(Res); + return Res; } std::variant @@ -1414,9 +1405,8 @@ Parser::ParseOpenACCBindClauseArgument() { return std::monostate{}; } - ExprResult Res = - getActions().CorrectDelayedTyposInExpr(ParseStringLiteralExpression( - /*AllowUserDefinedLiteral=*/false, /*Unevaluated=*/true)); + ExprResult Res = ParseStringLiteralExpression( + /*AllowUserDefinedLiteral=*/false, /*Unevaluated=*/true); if (!Res.isUsable()) return std::monostate{}; return cast(Res.get()); @@ -1430,10 +1420,6 @@ Parser::OpenACCVarParseResult Parser::ParseOpenACCVar(OpenACCDirectiveKind DK, if (!Res.isUsable()) return {Res, OpenACCParseCanContinue::Cannot}; - Res = getActions().CorrectDelayedTyposInExpr(Res.get()); - if (!Res.isUsable()) - return {Res, OpenACCParseCanContinue::Can}; - Res = getActions().OpenACC().ActOnVar(DK, CK, Res.get()); return {Res, OpenACCParseCanContinue::Can}; diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index e41e5ba8596b9..c8c83550cbb5e 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -3589,8 +3589,7 @@ bool Parser::ParseOMPInteropInfo(OMPInteropInfo &InteropInfo, while (Tok.isNot(tok::r_paren)) { SourceLocation Loc = Tok.getLocation(); ExprResult LHS = ParseCastExpression(CastParseKind::AnyCastExpr); - ExprResult PTExpr = Actions.CorrectDelayedTyposInExpr( - ParseRHSOfBinaryExpression(LHS, prec::Conditional)); + ExprResult PTExpr = ParseRHSOfBinaryExpression(LHS, prec::Conditional); PTExpr = Actions.ActOnFinishFullExpr(PTExpr.get(), Loc, /*DiscardedValue=*/false); if (PTExpr.isUsable()) { @@ -3651,8 +3650,7 @@ OMPClause *Parser::ParseOpenMPInteropClause(OpenMPClauseKind Kind, // Parse the variable. SourceLocation VarLoc = Tok.getLocation(); - ExprResult InteropVarExpr = - Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); + ExprResult InteropVarExpr = ParseAssignmentExpression(); if (!InteropVarExpr.isUsable()) { SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); @@ -4277,8 +4275,7 @@ ExprResult Parser::ParseOpenMPIteratorsExpr() { // Parse SourceLocation Loc = Tok.getLocation(); ExprResult LHS = ParseCastExpression(CastParseKind::AnyCastExpr); - ExprResult Begin = Actions.CorrectDelayedTyposInExpr( - ParseRHSOfBinaryExpression(LHS, prec::Conditional)); + ExprResult Begin = ParseRHSOfBinaryExpression(LHS, prec::Conditional); Begin = Actions.ActOnFinishFullExpr(Begin.get(), Loc, /*DiscardedValue=*/false); // Parse ':'. @@ -4289,8 +4286,7 @@ ExprResult Parser::ParseOpenMPIteratorsExpr() { // Parse Loc = Tok.getLocation(); LHS = ParseCastExpression(CastParseKind::AnyCastExpr); - ExprResult End = Actions.CorrectDelayedTyposInExpr( - ParseRHSOfBinaryExpression(LHS, prec::Conditional)); + ExprResult End = ParseRHSOfBinaryExpression(LHS, prec::Conditional); End = Actions.ActOnFinishFullExpr(End.get(), Loc, /*DiscardedValue=*/false); @@ -4303,8 +4299,7 @@ ExprResult Parser::ParseOpenMPIteratorsExpr() { // Parse Loc = Tok.getLocation(); LHS = ParseCastExpression(CastParseKind::AnyCastExpr); - Step = Actions.CorrectDelayedTyposInExpr( - ParseRHSOfBinaryExpression(LHS, prec::Conditional)); + Step = ParseRHSOfBinaryExpression(LHS, prec::Conditional); Step = Actions.ActOnFinishFullExpr(Step.get(), Loc, /*DiscardedValue=*/false); } @@ -4786,7 +4781,6 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope); Tail = ParseOpenMPIteratorsExpr(); } - Tail = Actions.CorrectDelayedTyposInExpr(Tail); Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(), /*DiscardedValue=*/false); if (Tail.isUsable() || Data.AllocateAlignment) { @@ -4846,8 +4840,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail); if (!ParseOpenMPReservedLocator(Kind, Data, getLangOpts())) { // Parse variable - ExprResult VarExpr = - Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); + ExprResult VarExpr = ParseAssignmentExpression(); if (VarExpr.isUsable()) { Vars.push_back(VarExpr.get()); } else { @@ -4884,6 +4877,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, SourceLocation ELoc = ConsumeToken(); if (getLangOpts().OpenMP >= 52 && Kind == OMPC_linear) { + bool Malformed = false; while (Tok.isNot(tok::r_paren)) { if (Tok.is(tok::identifier)) { // identifier could be a linear kind (val, uval, ref) or step @@ -4920,6 +4914,11 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, ModifierFound = true; } else { StepFound = parseStepSize(*this, Data, Kind, Tok.getLocation()); + if (!StepFound) { + Malformed = true; + SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, + StopBeforeMatch); + } } } else { // parse an integer expression as step size @@ -4931,7 +4930,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end)) break; } - if (!StepFound && !ModifierFound) + if (!Malformed && !StepFound && !ModifierFound) Diag(ELoc, diag::err_expected_expression); } else { // for OMPC_aligned and OMPC_linear (with OpenMP <= 5.1) diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index c788723023c8b..e680aaa361f36 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -602,7 +602,7 @@ StmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) { { ParseScopeFlags FilterScope(this, getCurScope()->getFlags() | Scope::SEHFilterScope); - FilterExpr = Actions.CorrectDelayedTyposInExpr(ParseExpression()); + FilterExpr = ParseExpression(); } if (getLangOpts().Borland) { @@ -1829,11 +1829,7 @@ StmtResult Parser::ParseDoStatement() { SourceLocation Start = Tok.getLocation(); ExprResult Cond = ParseExpression(); - // Correct the typos in condition before closing the scope. - if (Cond.isUsable()) - Cond = Actions.CorrectDelayedTyposInExpr(Cond, /*InitDecl=*/nullptr, - /*RecoverUncorrectedTypos=*/true); - else { + if (!Cond.isUsable()) { if (!Tok.isOneOf(tok::r_paren, tok::r_square, tok::r_brace)) SkipUntil(tok::semi); Cond = Actions.CreateRecoveryExpr( @@ -2015,7 +2011,7 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { } } else { ProhibitAttributes(attrs); - Value = Actions.CorrectDelayedTyposInExpr(ParseExpression()); + Value = ParseExpression(); ForEach = isTokIdentifier_in(); @@ -2174,12 +2170,10 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { StmtResult ForEachStmt; if (ForRangeInfo.ParsedForRangeDecl()) { - ExprResult CorrectedRange = - Actions.CorrectDelayedTyposInExpr(ForRangeInfo.RangeExpr.get()); ForRangeStmt = Actions.ActOnCXXForRangeStmt( getCurScope(), ForLoc, CoawaitLoc, FirstPart.get(), - ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc, CorrectedRange.get(), - T.getCloseLocation(), Sema::BFRK_Build, + ForRangeInfo.LoopVar.get(), ForRangeInfo.ColonLoc, + ForRangeInfo.RangeExpr.get(), T.getCloseLocation(), Sema::BFRK_Build, ForRangeInfo.LifetimeExtendTemps); } else if (ForEach) { // Similarly, we need to do the semantic analysis for a for-range diff --git a/clang/lib/Parse/ParseStmtAsm.cpp b/clang/lib/Parse/ParseStmtAsm.cpp index f2417479a0e78..182907df56070 100644 --- a/clang/lib/Parse/ParseStmtAsm.cpp +++ b/clang/lib/Parse/ParseStmtAsm.cpp @@ -864,7 +864,7 @@ bool Parser::ParseAsmOperandsOpt(SmallVectorImpl &Names, // Read the parenthesized expression. BalancedDelimiterTracker T(*this, tok::l_paren); T.consumeOpen(); - ExprResult Res = Actions.CorrectDelayedTyposInExpr(ParseExpression()); + ExprResult Res = ParseExpression(); T.consumeClose(); if (Res.isInvalid()) { SkipUntil(tok::r_paren, StopAtSemi); diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index d3c9ca029c9aa..a16dbe95b788d 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -296,8 +296,7 @@ Parser::ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo, return nullptr; } - ExprResult ConstraintExprResult = - Actions.CorrectDelayedTyposInExpr(ParseConstraintExpression()); + ExprResult ConstraintExprResult = ParseConstraintExpression(); if (ConstraintExprResult.isInvalid()) { SkipUntil(tok::semi); if (D) diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 9826abc0c3b40..42ebf2a508a26 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1227,15 +1227,6 @@ void Sema::ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind) { assert(LateParsedInstantiations.empty() && "end of TU template instantiation should not create more " "late-parsed templates"); - - // Report diagnostics for uncorrected delayed typos. Ideally all of them - // should have been corrected by that time, but it is very hard to cover all - // cases in practice. - for (const auto &Typo : DelayedTypos) { - // We pass an empty TypoCorrection to indicate no correction was performed. - Typo.second.DiagHandler(TypoCorrection()); - } - DelayedTypos.clear(); } void Sema::ActOnEndOfTranslationUnit() { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 8f8e1ceb7197e..69276ce418fa6 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2648,8 +2648,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete; ExprResult Res = BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete); - if (Res.isInvalid()) - CorrectDelayedTyposInExpr(TheCallResult.get()); return Res; } case Builtin::BI__builtin_dump_struct: diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp index 425b32e53a7b7..a1389c6c034b1 100644 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -309,15 +309,6 @@ static ExprResult buildMemberCall(Sema &S, Expr *Base, SourceLocation Loc, if (Result.isInvalid()) return ExprError(); - // We meant exactly what we asked for. No need for typo correction. - if (auto *TE = dyn_cast(Result.get())) { - S.clearDelayedTypo(TE); - S.Diag(Loc, diag::err_no_member) - << NameInfo.getName() << Base->getType()->getAsCXXRecordDecl() - << Base->getSourceRange(); - return ExprError(); - } - auto EndLoc = Args.empty() ? Loc : Args.back()->getEndLoc(); return S.BuildCallExpr(nullptr, Result.get(), Loc, Args, EndLoc, nullptr); } @@ -811,7 +802,6 @@ ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) { return ExprError(); if (!ActOnCoroutineBodyStart(S, Loc, "co_await")) { - CorrectDelayedTyposInExpr(E); return ExprError(); } @@ -970,7 +960,6 @@ ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) { return ExprError(); if (!ActOnCoroutineBodyStart(S, Loc, "co_yield")) { - CorrectDelayedTyposInExpr(E); return ExprError(); } @@ -1025,7 +1014,6 @@ ExprResult Sema::BuildCoyieldExpr(SourceLocation Loc, Expr *E) { StmtResult Sema::ActOnCoreturnStmt(Scope *S, SourceLocation Loc, Expr *E) { if (!ActOnCoroutineBodyStart(S, Loc, "co_return")) { - CorrectDelayedTyposInExpr(E); return StmtError(); } return BuildCoreturnStmt(Loc, E); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index bbd63372c168b..c152f406b4977 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -13584,7 +13584,6 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { // If there is no declaration, there was an error parsing it. Just ignore // the initializer. if (!RealDecl) { - CorrectDelayedTyposInExpr(Init, dyn_cast_or_null(RealDecl)); return; } @@ -13607,12 +13606,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { } if (VDecl->isInvalidDecl()) { - ExprResult Res = CorrectDelayedTyposInExpr(Init, VDecl); - SmallVector SubExprs; - if (Res.isUsable()) - SubExprs.push_back(Res.get()); ExprResult Recovery = - CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), SubExprs); + CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), {Init}); if (Expr *E = Recovery.get()) VDecl->setInit(E); return; @@ -13627,23 +13622,12 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for. if (VDecl->getType()->isUndeducedType()) { - // Attempt typo correction early so that the type of the init expression can - // be deduced based on the chosen correction if the original init contains a - // TypoExpr. - ExprResult Res = CorrectDelayedTyposInExpr(Init, VDecl); - if (!Res.isUsable()) { - // There are unresolved typos in Init, just drop them. - // FIXME: improve the recovery strategy to preserve the Init. - RealDecl->setInvalidDecl(); - return; - } - if (Res.get()->containsErrors()) { + if (Init->containsErrors()) { // Invalidate the decl as we don't know the type for recovery-expr yet. RealDecl->setInvalidDecl(); - VDecl->setInit(Res.get()); + VDecl->setInit(Init); return; } - Init = Res.get(); if (DeduceVariableDeclarationType(VDecl, DirectInit, Init)) return; @@ -13789,23 +13773,6 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { InitializedFromParenListExpr = true; } - // Try to correct any TypoExprs in the initialization arguments. - for (size_t Idx = 0; Idx < Args.size(); ++Idx) { - ExprResult Res = CorrectDelayedTyposInExpr( - Args[Idx], VDecl, /*RecoverUncorrectedTypos=*/true, - [this, Entity, Kind](Expr *E) { - InitializationSequence Init(*this, Entity, Kind, MultiExprArg(E)); - return Init.Failed() ? ExprError() : E; - }); - if (!Res.isUsable()) { - VDecl->setInvalidDecl(); - } else if (Res.get() != Args[Idx]) { - Args[Idx] = Res.get(); - } - } - if (VDecl->isInvalidDecl()) - return; - InitializationSequence InitSeq(*this, Entity, Kind, Args, /*TopLevelOfInitList=*/false, /*TreatUnavailableAsInvalid=*/false); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 39d4d49a0fe79..31e2834336742 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4154,10 +4154,6 @@ ExprResult Sema::ActOnRequiresClause(ExprResult ConstraintExpr) { if (ConstraintExpr.isInvalid()) return ExprError(); - ConstraintExpr = CorrectDelayedTyposInExpr(ConstraintExpr); - if (ConstraintExpr.isInvalid()) - return ExprError(); - if (DiagnoseUnexpandedParameterPack(ConstraintExpr.get(), UPPC_RequiresClause)) return ExprError(); @@ -4207,23 +4203,20 @@ void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D, return; } - ExprResult Init = CorrectDelayedTyposInExpr(InitExpr, /*InitDecl=*/nullptr, - /*RecoverUncorrectedTypos=*/true); - assert(Init.isUsable() && "Init should at least have a RecoveryExpr"); - if (!FD->getType()->isDependentType() && !Init.get()->isTypeDependent()) { - Init = ConvertMemberDefaultInitExpression(FD, Init.get(), InitLoc); + if (!FD->getType()->isDependentType() && !InitExpr.get()->isTypeDependent()) { + InitExpr = ConvertMemberDefaultInitExpression(FD, InitExpr.get(), InitLoc); // C++11 [class.base.init]p7: // The initialization of each base and member constitutes a // full-expression. - if (!Init.isInvalid()) - Init = ActOnFinishFullExpr(Init.get(), /*DiscarededValue=*/false); - if (Init.isInvalid()) { + if (!InitExpr.isInvalid()) + InitExpr = ActOnFinishFullExpr(InitExpr.get(), /*DiscarededValue=*/false); + if (InitExpr.isInvalid()) { FD->setInvalidDecl(); return; } } - FD->setInClassInitializer(Init.get()); + FD->setInClassInitializer(InitExpr.get()); } /// Find the direct and/or virtual base specifiers that @@ -4393,13 +4386,7 @@ Sema::BuildMemInitializer(Decl *ConstructorD, SourceLocation IdLoc, Expr *Init, SourceLocation EllipsisLoc) { - ExprResult Res = CorrectDelayedTyposInExpr(Init, /*InitDecl=*/nullptr, - /*RecoverUncorrectedTypos=*/true); - if (!Res.isUsable()) - return true; - Init = Res.get(); - - if (!ConstructorD) + if (!ConstructorD || !Init) return true; AdjustDeclIfTemplate(ConstructorD); diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index c692f824da422..0a6cea8869c14 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1368,7 +1368,6 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Expr::UnaryExprOrTypeTraitExprClass: case Expr::UnresolvedLookupExprClass: case Expr::UnresolvedMemberExprClass: - case Expr::TypoExprClass: // FIXME: Many of the above can throw. return CT_Cannot; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c7abbbd6993de..b7031bc8c0220 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2544,8 +2544,7 @@ bool Sema::DiagnoseDependentMemberLookup(const LookupResult &R) { bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, CorrectionCandidateCallback &CCC, TemplateArgumentListInfo *ExplicitTemplateArgs, - ArrayRef Args, DeclContext *LookupCtx, - TypoExpr **Out) { + ArrayRef Args, DeclContext *LookupCtx) { DeclarationName Name = R.getLookupName(); SourceRange NameRange = R.getLookupNameInfo().getSourceRange(); @@ -2604,21 +2603,9 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, // We didn't find anything, so try to correct for a typo. TypoCorrection Corrected; - if (S && Out) { - assert(!ExplicitTemplateArgs && - "Diagnosing an empty lookup with explicit template args!"); - *Out = CorrectTypoDelayed( - R.getLookupNameInfo(), R.getLookupKind(), S, &SS, CCC, - [=](const TypoCorrection &TC) { - emitEmptyLookupTypoDiagnostic(TC, *this, SS, Name, NameRange, - diagnostic, diagnostic_suggest); - }, - nullptr, CorrectTypoKind::ErrorRecovery, LookupCtx); - if (*Out) - return true; - } else if (S && (Corrected = CorrectTypo( - R.getLookupNameInfo(), R.getLookupKind(), S, &SS, CCC, - CorrectTypoKind::ErrorRecovery, LookupCtx))) { + if (S && (Corrected = + CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS, + CCC, CorrectTypoKind::ErrorRecovery, LookupCtx))) { std::string CorrectedStr(Corrected.getAsString(getLangOpts())); bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && Name.getAsString() == CorrectedStr; @@ -2880,7 +2867,6 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, // If this name wasn't predeclared and if this is not a function // call, diagnose the problem. - TypoExpr *TE = nullptr; DefaultFilterCCC DefaultValidator(II, SS.isValid() ? SS.getScopeRep() : nullptr); DefaultValidator.IsAddressOfOperand = IsAddressOfOperand; @@ -2896,29 +2882,8 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, // a template name, but we happen to have always already looked up the name // before we get here if it must be a template name. if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator, nullptr, - {}, nullptr, &TE)) { - 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(); - } + {}, nullptr)) + return ExprError(); assert(!R.empty() && "DiagnoseEmptyLookup returned false but added no results"); @@ -7009,40 +6974,6 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, CurFPFeatureOverrides(), NumParams, UsesADL); } - if (!Context.isDependenceAllowed()) { - // Forget about the nulled arguments since typo correction - // do not handle them well. - TheCall->shrinkNumArgs(Args.size()); - // C cannot always handle TypoExpr nodes in builtin calls and direct - // function calls as their argument checking don't necessarily handle - // dependent types properly, so make sure any TypoExprs have been - // dealt with. - ExprResult Result = CorrectDelayedTyposInExpr(TheCall); - if (!Result.isUsable()) return ExprError(); - CallExpr *TheOldCall = TheCall; - TheCall = dyn_cast(Result.get()); - bool CorrectedTypos = TheCall != TheOldCall; - if (!TheCall) return Result; - Args = llvm::ArrayRef(TheCall->getArgs(), TheCall->getNumArgs()); - - // A new call expression node was created if some typos were corrected. - // However it may not have been constructed with enough storage. In this - // case, rebuild the node with enough storage. The waste of space is - // immaterial since this only happens when some typos were corrected. - if (CorrectedTypos && Args.size() < NumParams) { - if (Config) - TheCall = CUDAKernelCallExpr::Create( - Context, Fn, cast(Config), Args, ResultTy, VK_PRValue, - RParenLoc, CurFPFeatureOverrides(), NumParams); - else - TheCall = - CallExpr::Create(Context, Fn, Args, ResultTy, VK_PRValue, RParenLoc, - CurFPFeatureOverrides(), NumParams, UsesADL); - } - // We can now handle the nulled arguments for the default arguments. - TheCall->setNumArgsUnsafe(std::max(Args.size(), NumParams)); - } - // Bail out early if calling a builtin with custom type checking. if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID)) { ExprResult E = CheckBuiltinFunctionCall(FDecl, BuiltinID, TheCall); @@ -7933,12 +7864,6 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, if (getLangOpts().CPlusPlus) { // Check that there are no default arguments (C++ only). CheckExtraCXXDefaultArguments(D); - } else { - // Make sure any TypoExprs have been dealt with. - ExprResult Res = CorrectDelayedTyposInExpr(CastExpr); - if (!Res.isUsable()) - return ExprError(); - CastExpr = Res.get(); } checkUnusedDeclAttributes(D); @@ -8984,30 +8909,6 @@ ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr) { - if (!Context.isDependenceAllowed()) { - // C cannot handle TypoExpr nodes in the condition because it - // doesn't handle dependent types properly, so make sure any TypoExprs have - // been dealt with before checking the operands. - ExprResult CondResult = CorrectDelayedTyposInExpr(CondExpr); - ExprResult LHSResult = CorrectDelayedTyposInExpr(LHSExpr); - ExprResult RHSResult = CorrectDelayedTyposInExpr(RHSExpr); - - if (!CondResult.isUsable()) - return ExprError(); - - if (LHSExpr) { - if (!LHSResult.isUsable()) - return ExprError(); - } - - if (!RHSResult.isUsable()) - return ExprError(); - - CondExpr = CondResult.get(); - LHSExpr = LHSResult.get(); - RHSExpr = RHSResult.get(); - } - // If this is the gnu "x ?: y" extension, analyze the types as though the LHS // was the condition. OpaqueValueExpr *opaqueValue = nullptr; @@ -15068,28 +14969,6 @@ static ExprResult convertHalfVecBinOp(Sema &S, ExprResult LHS, ExprResult RHS, return convertVector(BO, ResultTy->castAs()->getElementType(), S); } -static std::pair -CorrectDelayedTyposInBinOp(Sema &S, BinaryOperatorKind Opc, Expr *LHSExpr, - Expr *RHSExpr) { - ExprResult LHS = LHSExpr, RHS = RHSExpr; - if (!S.Context.isDependenceAllowed()) { - // C cannot handle TypoExpr nodes on either side of a binop because it - // doesn't handle dependent types properly, so make sure any TypoExprs have - // been dealt with before checking the operands. - LHS = S.CorrectDelayedTyposInExpr(LHS); - RHS = S.CorrectDelayedTyposInExpr( - RHS, /*InitDecl=*/nullptr, /*RecoverUncorrectedTypos=*/false, - [Opc, LHS](Expr *E) { - if (Opc != BO_Assign) - return ExprResult(E); - // Avoid correcting the RHS to the same Expr as the LHS. - Decl *D = getDeclFromExpr(E); - return (D && D == getDeclFromExpr(LHS.get())) ? ExprError() : E; - }); - } - return std::make_pair(LHS, RHS); -} - /// Returns true if conversion between vectors of halfs and vectors of floats /// is needed. static bool needsConversionOfHalfVec(bool OpRequiresConversion, ASTContext &Ctx, @@ -15146,7 +15025,6 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, ExprObjectKind OK = OK_Ordinary; bool ConvertHalfVec = false; - std::tie(LHS, RHS) = CorrectDelayedTyposInBinOp(*this, Opc, LHSExpr, RHSExpr); if (!LHS.isUsable() || !RHS.isUsable()) return ExprError(); @@ -15662,12 +15540,8 @@ static ExprResult BuildOverloadedBinOp(Sema &S, Scope *Sc, SourceLocation OpLoc, ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr, bool ForFoldExpression) { - ExprResult LHS, RHS; - std::tie(LHS, RHS) = CorrectDelayedTyposInBinOp(*this, Opc, LHSExpr, RHSExpr); - if (!LHS.isUsable() || !RHS.isUsable()) + if (!LHSExpr || !RHSExpr) return ExprError(); - LHSExpr = LHS.get(); - RHSExpr = RHS.get(); // We want to end up calling one of SemaPseudoObject::checkAssignment // (if the LHS is a pseudo-object), BuildOverloadedBinOp (if @@ -18194,8 +18068,6 @@ HandleImmediateInvocations(Sema &SemaRef, void Sema::PopExpressionEvaluationContext() { ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back(); - unsigned NumTypos = Rec.NumTypos; - if (!Rec.Lambdas.empty()) { using ExpressionKind = ExpressionEvaluationContextRecord::ExpressionKind; if (!getLangOpts().CPlusPlus20 && @@ -18263,9 +18135,6 @@ void Sema::PopExpressionEvaluationContext() { // Pop the current expression evaluation context off the stack. ExprEvalContexts.pop_back(); - - // The global expression evaluation context record is never popped. - ExprEvalContexts.back().NumTypos += NumTypos; } void Sema::DiscardCleanupsInEvaluationContext() { @@ -20023,8 +19892,6 @@ ExprResult Sema::CheckLValueToRValueConversionOperand(Expr *E) { } ExprResult Sema::ActOnConstantExpression(ExprResult Res) { - Res = CorrectDelayedTyposInExpr(Res); - if (!Res.isUsable()) return Res; @@ -21350,15 +21217,6 @@ static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) { } ExprResult Sema::CheckPlaceholderExpr(Expr *E) { - if (!Context.isDependenceAllowed()) { - // C cannot handle TypoExpr nodes on either side of a binop because it - // doesn't handle dependent types properly, so make sure any TypoExprs have - // been dealt with before checking the operands. - ExprResult Result = CorrectDelayedTyposInExpr(E); - if (!Result.isUsable()) return ExprError(); - E = Result.get(); - } - const BuiltinType *placeholderType = E->getType()->getAsPlaceholderType(); if (!placeholderType) return E; diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index c106ea749170f..c653cb56351cb 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1500,13 +1500,7 @@ Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep, auto Result = BuildCXXTypeConstructExpr(TInfo, LParenOrBraceLoc, exprs, RParenOrBraceLoc, ListInitialization); - // Avoid creating a non-type-dependent expression that contains typos. - // Non-type-dependent expressions are liable to be discarded without - // checking for embedded typos. - if (!Result.isInvalid() && Result.get()->isInstantiationDependent() && - !Result.get()->isTypeDependent()) - Result = CorrectDelayedTyposInExpr(Result.get()); - else if (Result.isInvalid()) + if (Result.isInvalid()) Result = CreateRecoveryExpr(TInfo->getTypeLoc().getBeginLoc(), RParenOrBraceLoc, exprs, Ty); return Result; @@ -7698,372 +7692,6 @@ static ExprResult attemptRecovery(Sema &SemaRef, /*AcceptInvalidDecl*/ true); } -namespace { -class FindTypoExprs : public DynamicRecursiveASTVisitor { - llvm::SmallSetVector &TypoExprs; - -public: - explicit FindTypoExprs(llvm::SmallSetVector &TypoExprs) - : TypoExprs(TypoExprs) {} - bool VisitTypoExpr(TypoExpr *TE) override { - TypoExprs.insert(TE); - return true; - } -}; - -class TransformTypos : public TreeTransform { - typedef TreeTransform BaseTransform; - - VarDecl *InitDecl; // A decl to avoid as a correction because it is in the - // process of being initialized. - llvm::function_ref ExprFilter; - llvm::SmallSetVector TypoExprs, AmbiguousTypoExprs; - llvm::SmallDenseMap TransformCache; - llvm::SmallDenseMap OverloadResolution; - - /// Emit diagnostics for all of the TypoExprs encountered. - /// - /// If the TypoExprs were successfully corrected, then the diagnostics should - /// suggest the corrections. Otherwise the diagnostics will not suggest - /// anything (having been passed an empty TypoCorrection). - /// - /// If we've failed to correct due to ambiguous corrections, we need to - /// be sure to pass empty corrections and replacements. Otherwise it's - /// possible that the Consumer has a TypoCorrection that failed to ambiguity - /// and we don't want to report those diagnostics. - void EmitAllDiagnostics(bool IsAmbiguous) { - for (TypoExpr *TE : TypoExprs) { - auto &State = SemaRef.getTypoExprState(TE); - if (State.DiagHandler) { - TypoCorrection TC = IsAmbiguous - ? TypoCorrection() : State.Consumer->getCurrentCorrection(); - ExprResult Replacement = IsAmbiguous ? ExprError() : TransformCache[TE]; - - // Extract the NamedDecl from the transformed TypoExpr and add it to the - // TypoCorrection, replacing the existing decls. This ensures the right - // NamedDecl is used in diagnostics e.g. in the case where overload - // resolution was used to select one from several possible decls that - // had been stored in the TypoCorrection. - if (auto *ND = getDeclFromExpr( - Replacement.isInvalid() ? nullptr : Replacement.get())) - TC.setCorrectionDecl(ND); - - State.DiagHandler(TC); - } - SemaRef.clearDelayedTypo(TE); - } - } - - /// Try to advance the typo correction state of the first unfinished TypoExpr. - /// We allow advancement of the correction stream by removing it from the - /// TransformCache which allows `TransformTypoExpr` to advance during the - /// next transformation attempt. - /// - /// Any substitution attempts for the previous TypoExprs (which must have been - /// finished) will need to be retried since it's possible that they will now - /// be invalid given the latest advancement. - /// - /// We need to be sure that we're making progress - it's possible that the - /// tree is so malformed that the transform never makes it to the - /// `TransformTypoExpr`. - /// - /// Returns true if there are any untried correction combinations. - bool CheckAndAdvanceTypoExprCorrectionStreams() { - for (auto *TE : TypoExprs) { - auto &State = SemaRef.getTypoExprState(TE); - TransformCache.erase(TE); - if (!State.Consumer->hasMadeAnyCorrectionProgress()) - return false; - if (!State.Consumer->finished()) - return true; - State.Consumer->resetCorrectionStream(); - } - return false; - } - - NamedDecl *getDeclFromExpr(Expr *E) { - if (auto *OE = dyn_cast_or_null(E)) - E = OverloadResolution[OE]; - - if (!E) - return nullptr; - if (auto *DRE = dyn_cast(E)) - return DRE->getFoundDecl(); - if (auto *ME = dyn_cast(E)) - return ME->getFoundDecl(); - // FIXME: Add any other expr types that could be seen by the delayed typo - // correction TreeTransform for which the corresponding TypoCorrection could - // contain multiple decls. - return nullptr; - } - - ExprResult TryTransform(Expr *E) { - Sema::SFINAETrap Trap(SemaRef); - ExprResult Res = TransformExpr(E); - if (Trap.hasErrorOccurred() || Res.isInvalid()) - return ExprError(); - - return ExprFilter(Res.get()); - } - - // Since correcting typos may intoduce new TypoExprs, this function - // checks for new TypoExprs and recurses if it finds any. Note that it will - // only succeed if it is able to correct all typos in the given expression. - ExprResult CheckForRecursiveTypos(ExprResult Res, bool &IsAmbiguous) { - if (Res.isInvalid()) { - return Res; - } - // Check to see if any new TypoExprs were created. If so, we need to recurse - // to check their validity. - Expr *FixedExpr = Res.get(); - - auto SavedTypoExprs = std::move(TypoExprs); - auto SavedAmbiguousTypoExprs = std::move(AmbiguousTypoExprs); - TypoExprs.clear(); - AmbiguousTypoExprs.clear(); - - FindTypoExprs(TypoExprs).TraverseStmt(FixedExpr); - if (!TypoExprs.empty()) { - // Recurse to handle newly created TypoExprs. If we're not able to - // handle them, discard these TypoExprs. - ExprResult RecurResult = - RecursiveTransformLoop(FixedExpr, IsAmbiguous); - if (RecurResult.isInvalid()) { - Res = ExprError(); - // Recursive corrections didn't work, wipe them away and don't add - // them to the TypoExprs set. Remove them from Sema's TypoExpr list - // since we don't want to clear them twice. Note: it's possible the - // TypoExprs were created recursively and thus won't be in our - // Sema's TypoExprs - they were created in our `RecursiveTransformLoop`. - auto &SemaTypoExprs = SemaRef.TypoExprs; - for (auto *TE : TypoExprs) { - TransformCache.erase(TE); - SemaRef.clearDelayedTypo(TE); - - auto SI = find(SemaTypoExprs, TE); - if (SI != SemaTypoExprs.end()) { - SemaTypoExprs.erase(SI); - } - } - } else { - // TypoExpr is valid: add newly created TypoExprs since we were - // able to correct them. - Res = RecurResult; - SavedTypoExprs.set_union(TypoExprs); - } - } - - TypoExprs = std::move(SavedTypoExprs); - AmbiguousTypoExprs = std::move(SavedAmbiguousTypoExprs); - - return Res; - } - - // Try to transform the given expression, looping through the correction - // candidates with `CheckAndAdvanceTypoExprCorrectionStreams`. - // - // If valid ambiguous typo corrections are seen, `IsAmbiguous` is set to - // true and this method immediately will return an `ExprError`. - ExprResult RecursiveTransformLoop(Expr *E, bool &IsAmbiguous) { - ExprResult Res; - auto SavedTypoExprs = std::move(SemaRef.TypoExprs); - SemaRef.TypoExprs.clear(); - - while (true) { - Res = CheckForRecursiveTypos(TryTransform(E), IsAmbiguous); - - // Recursion encountered an ambiguous correction. This means that our - // correction itself is ambiguous, so stop now. - if (IsAmbiguous) - break; - - // If the transform is still valid after checking for any new typos, - // it's good to go. - if (!Res.isInvalid()) - break; - - // The transform was invalid, see if we have any TypoExprs with untried - // correction candidates. - if (!CheckAndAdvanceTypoExprCorrectionStreams()) - break; - } - - // If we found a valid result, double check to make sure it's not ambiguous. - if (!IsAmbiguous && !Res.isInvalid() && !AmbiguousTypoExprs.empty()) { - auto SavedTransformCache = - llvm::SmallDenseMap(TransformCache); - - // Ensure none of the TypoExprs have multiple typo correction candidates - // with the same edit length that pass all the checks and filters. - while (!AmbiguousTypoExprs.empty()) { - auto TE = AmbiguousTypoExprs.back(); - - // TryTransform itself can create new Typos, adding them to the TypoExpr map - // and invalidating our TypoExprState, so always fetch it instead of storing. - SemaRef.getTypoExprState(TE).Consumer->saveCurrentPosition(); - - TypoCorrection TC = SemaRef.getTypoExprState(TE).Consumer->peekNextCorrection(); - TypoCorrection Next; - do { - // Fetch the next correction by erasing the typo from the cache and calling - // `TryTransform` which will iterate through corrections in - // `TransformTypoExpr`. - TransformCache.erase(TE); - ExprResult AmbigRes = CheckForRecursiveTypos(TryTransform(E), IsAmbiguous); - - if (!AmbigRes.isInvalid() || IsAmbiguous) { - SemaRef.getTypoExprState(TE).Consumer->resetCorrectionStream(); - SavedTransformCache.erase(TE); - Res = ExprError(); - IsAmbiguous = true; - break; - } - } while ((Next = SemaRef.getTypoExprState(TE).Consumer->peekNextCorrection()) && - Next.getEditDistance(false) == TC.getEditDistance(false)); - - if (IsAmbiguous) - break; - - AmbiguousTypoExprs.remove(TE); - SemaRef.getTypoExprState(TE).Consumer->restoreSavedPosition(); - TransformCache[TE] = SavedTransformCache[TE]; - } - TransformCache = std::move(SavedTransformCache); - } - - // Wipe away any newly created TypoExprs that we don't know about. Since we - // clear any invalid TypoExprs in `CheckForRecursiveTypos`, this is only - // possible if a `TypoExpr` is created during a transformation but then - // fails before we can discover it. - auto &SemaTypoExprs = SemaRef.TypoExprs; - for (auto Iterator = SemaTypoExprs.begin(); Iterator != SemaTypoExprs.end();) { - auto TE = *Iterator; - auto FI = find(TypoExprs, TE); - if (FI != TypoExprs.end()) { - Iterator++; - continue; - } - SemaRef.clearDelayedTypo(TE); - Iterator = SemaTypoExprs.erase(Iterator); - } - SemaRef.TypoExprs = std::move(SavedTypoExprs); - - return Res; - } - -public: - TransformTypos(Sema &SemaRef, VarDecl *InitDecl, llvm::function_ref Filter) - : BaseTransform(SemaRef), InitDecl(InitDecl), ExprFilter(Filter) {} - - ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc, - MultiExprArg Args, - SourceLocation RParenLoc, - Expr *ExecConfig = nullptr) { - auto Result = BaseTransform::RebuildCallExpr(Callee, LParenLoc, Args, - RParenLoc, ExecConfig); - if (auto *OE = dyn_cast(Callee)) { - if (Result.isUsable()) { - Expr *ResultCall = Result.get(); - if (auto *BE = dyn_cast(ResultCall)) - ResultCall = BE->getSubExpr(); - if (auto *CE = dyn_cast(ResultCall)) - OverloadResolution[OE] = CE->getCallee(); - } - } - return Result; - } - - ExprResult TransformLambdaExpr(LambdaExpr *E) { return Owned(E); } - - ExprResult TransformBlockExpr(BlockExpr *E) { return Owned(E); } - - ExprResult Transform(Expr *E) { - bool IsAmbiguous = false; - ExprResult Res = RecursiveTransformLoop(E, IsAmbiguous); - - if (!Res.isUsable()) - FindTypoExprs(TypoExprs).TraverseStmt(E); - - EmitAllDiagnostics(IsAmbiguous); - - return Res; - } - - ExprResult TransformTypoExpr(TypoExpr *E) { - // If the TypoExpr hasn't been seen before, record it. Otherwise, return the - // cached transformation result if there is one and the TypoExpr isn't the - // first one that was encountered. - auto &CacheEntry = TransformCache[E]; - if (!TypoExprs.insert(E) && !CacheEntry.isUnset()) { - return CacheEntry; - } - - auto &State = SemaRef.getTypoExprState(E); - assert(State.Consumer && "Cannot transform a cleared TypoExpr"); - - // For the first TypoExpr and an uncached TypoExpr, find the next likely - // typo correction and return it. - while (TypoCorrection TC = State.Consumer->getNextCorrection()) { - if (InitDecl && TC.getFoundDecl() == InitDecl) - continue; - // FIXME: If we would typo-correct to an invalid declaration, it's - // probably best to just suppress all errors from this typo correction. - ExprResult NE = State.RecoveryHandler ? - State.RecoveryHandler(SemaRef, E, TC) : - attemptRecovery(SemaRef, *State.Consumer, TC); - if (!NE.isInvalid()) { - // Check whether there may be a second viable correction with the same - // edit distance; if so, remember this TypoExpr may have an ambiguous - // correction so it can be more thoroughly vetted later. - TypoCorrection Next; - if ((Next = State.Consumer->peekNextCorrection()) && - Next.getEditDistance(false) == TC.getEditDistance(false)) { - AmbiguousTypoExprs.insert(E); - } else { - AmbiguousTypoExprs.remove(E); - } - assert(!NE.isUnset() && - "Typo was transformed into a valid-but-null ExprResult"); - return CacheEntry = NE; - } - } - return CacheEntry = ExprError(); - } -}; -} - -ExprResult -Sema::CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl, - bool RecoverUncorrectedTypos, - llvm::function_ref Filter) { - // If the current evaluation context indicates there are uncorrected typos - // and the current expression isn't guaranteed to not have typos, try to - // resolve any TypoExpr nodes that might be in the expression. - if (E && !ExprEvalContexts.empty() && ExprEvalContexts.back().NumTypos && - (E->isTypeDependent() || E->isValueDependent() || - E->isInstantiationDependent())) { - auto TyposResolved = DelayedTypos.size(); - auto Result = TransformTypos(*this, InitDecl, Filter).Transform(E); - TyposResolved -= DelayedTypos.size(); - if (Result.isInvalid() || Result.get() != E) { - ExprEvalContexts.back().NumTypos -= TyposResolved; - if (Result.isInvalid() && RecoverUncorrectedTypos) { - struct TyposReplace : TreeTransform { - TyposReplace(Sema &SemaRef) : TreeTransform(SemaRef) {} - ExprResult TransformTypoExpr(clang::TypoExpr *E) { - return this->SemaRef.CreateRecoveryExpr(E->getBeginLoc(), - E->getEndLoc(), {}); - } - } TT(*this); - return TT.TransformExpr(E); - } - return Result; - } - assert(TyposResolved == 0 && "Corrected typo but got same Expr back?"); - } - return E; -} - ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, bool DiscardedValue, bool IsConstexpr, bool IsTemplateArgument) { @@ -8095,8 +7723,6 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, DiagnoseUnusedExprResult(FullExpr.get(), diag::warn_unused_expr); } - FullExpr = CorrectDelayedTyposInExpr(FullExpr.get(), /*InitDecl=*/nullptr, - /*RecoverUncorrectedTypos=*/true); if (FullExpr.isInvalid()) return ExprError(); diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index 39c162c3b835d..5dca509d46fdb 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -650,64 +650,11 @@ bool Sema::CheckQualifiedMemberReference(Expr *BaseExpr, return true; } -namespace { - -// Callback to only accept typo corrections that are either a ValueDecl or a -// FunctionTemplateDecl and are declared in the current record or, for a C++ -// classes, one of its base classes. -class RecordMemberExprValidatorCCC final : public CorrectionCandidateCallback { -public: - explicit RecordMemberExprValidatorCCC(QualType RTy) - : Record(RTy->getAsRecordDecl()) { - // Don't add bare keywords to the consumer since they will always fail - // validation by virtue of not being associated with any decls. - WantTypeSpecifiers = false; - WantExpressionKeywords = false; - WantCXXNamedCasts = false; - WantFunctionLikeCasts = false; - WantRemainingKeywords = false; - } - - bool ValidateCandidate(const TypoCorrection &candidate) override { - NamedDecl *ND = candidate.getCorrectionDecl(); - // Don't accept candidates that cannot be member functions, constants, - // variables, or templates. - if (!ND || !(isa(ND) || isa(ND))) - return false; - - // Accept candidates that occur in the current record. - if (Record->containsDecl(ND)) - return true; - - if (const auto *RD = dyn_cast(Record)) { - // Accept candidates that occur in any of the current class' base classes. - for (const auto &BS : RD->bases()) { - if (const auto *BSTy = BS.getType()->getAs()) { - if (BSTy->getDecl()->containsDecl(ND)) - return true; - } - } - } - - return false; - } - - std::unique_ptr clone() override { - return std::make_unique(*this); - } - -private: - const RecordDecl *const Record; -}; - -} - static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, Expr *BaseExpr, QualType RTy, SourceLocation OpLoc, bool IsArrow, CXXScopeSpec &SS, bool HasTemplateArgs, - SourceLocation TemplateKWLoc, - TypoExpr *&TE) { + SourceLocation TemplateKWLoc) { SourceRange BaseRange = BaseExpr ? BaseExpr->getSourceRange() : SourceRange(); if (!RTy->isDependentType() && !SemaRef.isThisOutsideMemberFunctionBody(RTy) && @@ -724,56 +671,6 @@ static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, /*EnteringContext=*/false, TemplateKWLoc); SemaRef.LookupParsedName(R, /*S=*/nullptr, &SS, ObjectType); - - if (!R.empty() || R.wasNotFoundInCurrentInstantiation()) - return false; - - DeclarationName Typo = R.getLookupName(); - SourceLocation TypoLoc = R.getNameLoc(); - // Recompute the lookup context. - DeclContext *DC = SS.isSet() ? SemaRef.computeDeclContext(SS) - : SemaRef.computeDeclContext(RTy); - - struct QueryState { - Sema &SemaRef; - DeclarationNameInfo NameInfo; - Sema::LookupNameKind LookupKind; - RedeclarationKind Redecl; - }; - QueryState Q = {R.getSema(), R.getLookupNameInfo(), R.getLookupKind(), - R.redeclarationKind()}; - RecordMemberExprValidatorCCC CCC(RTy); - TE = SemaRef.CorrectTypoDelayed( - R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS, CCC, - [=, &SemaRef](const TypoCorrection &TC) { - if (TC) { - assert(!TC.isKeyword() && - "Got a keyword as a correction for a member!"); - bool DroppedSpecifier = - TC.WillReplaceSpecifier() && - Typo.getAsString() == TC.getAsString(SemaRef.getLangOpts()); - SemaRef.diagnoseTypo(TC, SemaRef.PDiag(diag::err_no_member_suggest) - << Typo << DC << DroppedSpecifier - << SS.getRange()); - } else { - SemaRef.Diag(TypoLoc, diag::err_no_member) - << Typo << DC << (SS.isSet() ? SS.getRange() : BaseRange); - } - }, - [=](Sema &SemaRef, TypoExpr *TE, TypoCorrection TC) mutable { - LookupResult R(Q.SemaRef, Q.NameInfo, Q.LookupKind, Q.Redecl); - R.clear(); // Ensure there's no decls lingering in the shared state. - R.suppressDiagnostics(); - R.setLookupName(TC.getCorrection()); - for (NamedDecl *ND : TC) - R.addDecl(ND); - R.resolveKind(); - return SemaRef.BuildMemberReferenceExpr( - BaseExpr, BaseExpr->getType(), OpLoc, IsArrow, SS, SourceLocation(), - nullptr, R, nullptr, nullptr); - }, - CorrectTypoKind::ErrorRecovery, DC); - return false; } @@ -793,15 +690,11 @@ ExprResult Sema::BuildMemberReferenceExpr( // Implicit member accesses. if (!Base) { - TypoExpr *TE = nullptr; QualType RecordTy = BaseType; if (IsArrow) RecordTy = RecordTy->castAs()->getPointeeType(); if (LookupMemberExprInRecord(*this, R, nullptr, RecordTy, OpLoc, IsArrow, - SS, TemplateArgs != nullptr, TemplateKWLoc, - TE)) + SS, TemplateArgs != nullptr, TemplateKWLoc)) return ExprError(); - if (TE) - return TE; // Explicit member accesses. } else { @@ -1396,16 +1289,15 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, // Handle field access to simple records. if (BaseType->getAsRecordDecl()) { - TypoExpr *TE = nullptr; if (LookupMemberExprInRecord(S, R, BaseExpr.get(), BaseType, OpLoc, IsArrow, - SS, HasTemplateArgs, TemplateKWLoc, TE)) + SS, HasTemplateArgs, TemplateKWLoc)) return ExprError(); // Returning valid-but-null is how we indicate to the caller that // the lookup result was filled in. If typo correction was attempted and // failed, the lookup result will have been cleared--that combined with the // valid-but-null ExprResult will trigger the appropriate diagnostics. - return ExprResult(TE); + return ExprResult{}; } else if (BaseType->isDependentType()) { R.setNotFoundInCurrentInstantiation(); return ExprEmpty(); diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index eef134b158438..0478f38249553 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -5431,40 +5431,6 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure && !SecondBestTC); } -TypoExpr *Sema::CorrectTypoDelayed( - const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind, - Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, - TypoDiagnosticGenerator TDG, TypoRecoveryCallback TRC, CorrectTypoKind Mode, - DeclContext *MemberContext, bool EnteringContext, - const ObjCObjectPointerType *OPT) { - auto Consumer = makeTypoCorrectionConsumer( - TypoName, LookupKind, S, SS, CCC, MemberContext, EnteringContext, OPT, - Mode == CorrectTypoKind::ErrorRecovery); - - // Give the external sema source a chance to correct the typo. - TypoCorrection ExternalTypo; - if (ExternalSource && Consumer) { - ExternalTypo = ExternalSource->CorrectTypo( - TypoName, LookupKind, S, SS, *Consumer->getCorrectionValidator(), - MemberContext, EnteringContext, OPT); - if (ExternalTypo) - Consumer->addCorrection(ExternalTypo); - } - - if (!Consumer || Consumer->empty()) - return nullptr; - - // Make sure the best edit distance (prior to adding any namespace qualifiers) - // is not more that about a third of the length of the typo's identifier. - unsigned ED = Consumer->getBestEditDistance(true); - IdentifierInfo *Typo = TypoName.getName().getAsIdentifierInfo(); - if (!ExternalTypo && ED > 0 && Typo->getName().size() / ED < 3) - return nullptr; - ExprEvalContexts.back().NumTypos++; - return createDelayedTypo(std::move(Consumer), std::move(TDG), std::move(TRC), - TypoName.getLoc()); -} - void TypoCorrection::addCorrectionDecl(NamedDecl *CDecl) { if (!CDecl) return; @@ -5789,32 +5755,6 @@ void Sema::diagnoseTypo(const TypoCorrection &Correction, Diag(Correction.getCorrectionRange().getBegin(), PD); } -TypoExpr *Sema::createDelayedTypo(std::unique_ptr TCC, - TypoDiagnosticGenerator TDG, - TypoRecoveryCallback TRC, - SourceLocation TypoLoc) { - assert(TCC && "createDelayedTypo requires a valid TypoCorrectionConsumer"); - auto TE = new (Context) TypoExpr(Context.DependentTy, TypoLoc); - auto &State = DelayedTypos[TE]; - State.Consumer = std::move(TCC); - State.DiagHandler = std::move(TDG); - State.RecoveryHandler = std::move(TRC); - if (TE) - TypoExprs.push_back(TE); - return TE; -} - -const Sema::TypoExprState &Sema::getTypoExprState(TypoExpr *TE) const { - auto Entry = DelayedTypos.find(TE); - assert(Entry != DelayedTypos.end() && - "Failed to get the state for a TypoExpr!"); - return Entry->second; -} - -void Sema::clearDelayedTypo(TypoExpr *TE) { - DelayedTypos.erase(TE); -} - void Sema::ActOnPragmaDump(Scope *S, SourceLocation IILoc, IdentifierInfo *II) { DeclarationNameInfo Name(II, IILoc); LookupResult R(*this, Name, LookupAnyName, diff --git a/clang/lib/Sema/SemaObjC.cpp b/clang/lib/Sema/SemaObjC.cpp index 56815cd2731a1..0f39a9817ce7f 100644 --- a/clang/lib/Sema/SemaObjC.cpp +++ b/clang/lib/Sema/SemaObjC.cpp @@ -124,17 +124,12 @@ ExprResult SemaObjC::CheckObjCForCollectionOperand(SourceLocation forLoc, if (!collection) return ExprError(); - ExprResult result = SemaRef.CorrectDelayedTyposInExpr(collection); - if (!result.isUsable()) - return ExprError(); - collection = result.get(); - // Bail out early if we've got a type-dependent expression. if (collection->isTypeDependent()) return collection; // Perform normal l-value conversion. - result = SemaRef.DefaultFunctionArrayLvalueConversion(collection); + ExprResult result = SemaRef.DefaultFunctionArrayLvalueConversion(collection); if (result.isInvalid()) return ExprError(); collection = result.get(); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index cf455f4588de3..bdb8bae780c49 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -14055,8 +14055,10 @@ FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization( // specified and it, along with any default template arguments, // identifies a single function template specialization, then the // template-id is an lvalue for the function template specialization. - FunctionTemplateDecl *FunctionTemplate - = cast((*I)->getUnderlyingDecl()); + FunctionTemplateDecl *FunctionTemplate = + dyn_cast((*I)->getUnderlyingDecl()); + if (!FunctionTemplate) + continue; // C++ [over.over]p2: // If the name is a function template, template argument deduction is diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 50f5757dff5bc..923a9e81fbd6a 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -535,12 +535,7 @@ Sema::ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val) { return ER; }; - ExprResult Converted = CorrectDelayedTyposInExpr( - Val, /*InitDecl=*/nullptr, /*RecoverUncorrectedTypos=*/false, - CheckAndFinish); - if (Converted.get() == Val.get()) - Converted = CheckAndFinish(Val.get()); - return Converted; + return CheckAndFinish(Val.get()); } StmtResult @@ -2344,7 +2339,7 @@ StmtResult Sema::ActOnForEachLValueExpr(Expr *E) { static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init, SourceLocation Loc, int DiagID) { if (Decl->getType()->isUndeducedType()) { - ExprResult Res = SemaRef.CorrectDelayedTyposInExpr(Init); + ExprResult Res = Init; if (!Res.isUsable()) { Decl->setInvalidDecl(); return true; @@ -3845,10 +3840,7 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, StmtResult Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, Scope *CurScope) { - // Correct typos, in case the containing function returns 'auto' and - // RetValExp should determine the deduced type. - ExprResult RetVal = CorrectDelayedTyposInExpr( - RetValExp, nullptr, /*RecoverUncorrectedTypos=*/true); + ExprResult RetVal = RetValExp; if (RetVal.isInvalid()) return StmtError(); diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index 17da5fd8325be..b78080c991763 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -782,11 +782,10 @@ ExprResult Sema::ActOnCXXAssumeAttr(Stmt *St, const ParsedAttr &A, ExprResult Sema::BuildCXXAssumeExpr(Expr *Assumption, const IdentifierInfo *AttrName, SourceRange Range) { - ExprResult Res = CorrectDelayedTyposInExpr(Assumption); - if (Res.isInvalid()) + if (!Assumption) return ExprError(); - Res = CheckPlaceholderExpr(Res.get()); + ExprResult Res = CheckPlaceholderExpr(Assumption); if (Res.isInvalid()) return ExprError(); diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index 5f0e968ff18c4..572dbf2e7393f 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -741,7 +741,6 @@ ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc, if (!Pattern->containsUnexpandedParameterPack()) { Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) << Pattern->getSourceRange(); - CorrectDelayedTyposInExpr(Pattern); return ExprError(); } @@ -1201,11 +1200,9 @@ ExprResult Sema::ActOnPackIndexingExpr(Scope *S, Expr *PackExpression, SourceLocation RSquareLoc) { bool isParameterPack = ::isParameterPack(PackExpression); if (!isParameterPack) { - if (!PackExpression->containsErrors()) { - CorrectDelayedTyposInExpr(IndexExpr); + if (!PackExpression->containsErrors()) Diag(PackExpression->getBeginLoc(), diag::err_expected_name_of_pack) << PackExpression; - } return ExprError(); } ExprResult Res = @@ -1403,11 +1400,6 @@ ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS, CheckFoldOperand(*this, LHS); CheckFoldOperand(*this, RHS); - auto DiscardOperands = [&] { - CorrectDelayedTyposInExpr(LHS); - CorrectDelayedTyposInExpr(RHS); - }; - // [expr.prim.fold]p3: // In a binary fold, op1 and op2 shall be the same fold-operator, and // either e1 shall contain an unexpanded parameter pack or e2 shall contain @@ -1415,7 +1407,6 @@ ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS, if (LHS && RHS && LHS->containsUnexpandedParameterPack() == RHS->containsUnexpandedParameterPack()) { - DiscardOperands(); return Diag(EllipsisLoc, LHS->containsUnexpandedParameterPack() ? diag::err_fold_expression_packs_both_sides @@ -1430,7 +1421,6 @@ ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS, Expr *Pack = LHS ? LHS : RHS; assert(Pack && "fold expression with neither LHS nor RHS"); if (!Pack->containsUnexpandedParameterPack()) { - DiscardOperands(); return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) << Pack->getSourceRange(); } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index c8d29f0a625f8..3e33fb73e01b4 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -13121,12 +13121,6 @@ TreeTransform::TransformOpaqueValueExpr(OpaqueValueExpr *E) { return E; } -template -ExprResult -TreeTransform::TransformTypoExpr(TypoExpr *E) { - return E; -} - template ExprResult TreeTransform::TransformRecoveryExpr(RecoveryExpr *E) { llvm::SmallVector Children; diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 01c838b955755..65102b64030c6 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2310,10 +2310,6 @@ void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) { E->setIsUnique(Record.readInt()); } -void ASTStmtReader::VisitTypoExpr(TypoExpr *E) { - llvm_unreachable("Cannot read TypoExpr nodes"); -} - void ASTStmtReader::VisitRecoveryExpr(RecoveryExpr *E) { VisitExpr(E); unsigned NumArgs = Record.readInt(); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 767e7405752c2..a6e320c7f3eb0 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -2314,12 +2314,6 @@ void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) { Code = serialization::EXPR_OPAQUE_VALUE; } -void ASTStmtWriter::VisitTypoExpr(TypoExpr *E) { - VisitExpr(E); - // TODO: Figure out sane writer behavior for a TypoExpr, if necessary - llvm_unreachable("Cannot write TypoExpr nodes"); -} - //===----------------------------------------------------------------------===// // CUDA Expressions and Statements. //===----------------------------------------------------------------------===// diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index b28deee41d1c5..c77ef26da568d 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1732,7 +1732,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::ExpressionTraitExprClass: case Stmt::UnresolvedLookupExprClass: case Stmt::UnresolvedMemberExprClass: - case Stmt::TypoExprClass: case Stmt::RecoveryExprClass: case Stmt::CXXNoexceptExprClass: case Stmt::PackExpansionExprClass: diff --git a/clang/test/AST/ByteCode/literals.cpp b/clang/test/AST/ByteCode/literals.cpp index 2fa7b69b93470..699746c0b2c4a 100644 --- a/clang/test/AST/ByteCode/literals.cpp +++ b/clang/test/AST/ByteCode/literals.cpp @@ -910,7 +910,8 @@ namespace CompoundLiterals { constexpr int f2(int *x =(int[]){1,2,3}) { return x[0]; } - constexpr int g = f2(); // Should evaluate to 1? + // Should evaluate to 1? + constexpr int g = f2(); // #g_decl static_assert(g == 1, ""); // This example should be rejected because the lifetime of the compound @@ -1347,7 +1348,10 @@ namespace NTTP { namespace UnaryOpError { constexpr int foo() { int f = 0; - ++g; // both-error {{use of undeclared identifier 'g'}} + ++g; // both-error {{use of undeclared identifier 'g'}} \ + both-error {{cannot assign to variable 'g' with const-qualified type 'const int'}} \ + both-note@#g_decl {{'CompoundLiterals::g' declared here}} \ + both-note@#g_decl {{variable 'g' declared const here}} return f; } } diff --git a/clang/test/AST/ast-dump-recovery.c b/clang/test/AST/ast-dump-recovery.c index 68d3f182dd9f6..09a03fb9d6fdf 100644 --- a/clang/test/AST/ast-dump-recovery.c +++ b/clang/test/AST/ast-dump-recovery.c @@ -23,13 +23,6 @@ int postfix_inc = a++; // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' int unary_address = &(a + 1); -// CHECK: VarDecl {{.*}} ternary 'int' cinit -// CHECK-NEXT: `-ConditionalOperator {{.*}} -// CHECK-NEXT: |-DeclRefExpr {{.*}} 'a' -// CHECK-NEXT: |-RecoveryExpr {{.*}} -// CHECK-NEXT: `-DeclRefExpr {{.*}} 'a' -int ternary = a ? undef : a; - void test1() { // CHECK: `-RecoveryExpr {{.*}} contains-errors // CHECK-NEXT: `-DeclRefExpr {{.*}} 'a' 'const int' @@ -91,12 +84,6 @@ void test3() { // CHECK-NEXT: | `-DeclRefExpr {{.*}} '__builtin_classify_type' // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1 (*__builtin_classify_type)(1); - - extern void ext(); - // CHECK: CallExpr {{.*}} '' contains-errors - // CHECK-NEXT: |-DeclRefExpr {{.*}} 'ext' - // CHECK-NEXT: `-RecoveryExpr {{.*}} '' - ext(undef_var); } // Verify no crash. @@ -110,23 +97,6 @@ void test4() { }; } -// Verify no crash -void test5_GH62711() { - // CHECK: VAArgExpr {{.*}} 'int' contains-errors - // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '' contains-errors - // CHECK-NEXT: | `-RecoveryExpr {{.*}} '' contains-errors - if (__builtin_va_arg(undef, int) << 1); -} - -void test6_GH50244() { - double array[16]; - // CHECK: UnaryExprOrTypeTraitExpr {{.*}} 'unsigned long' contains-errors sizeof - // CHECK-NEXT: `-CallExpr {{.*}} '' contains-errors - // CHECK-NEXT: |-DeclRefExpr {{.*}} 'int ()' - // CHECK-NEXT: `-RecoveryExpr {{.*}} '' - sizeof array / sizeof foo(undef); -} - // No crash on DeclRefExpr that refers to ValueDecl with invalid initializers. void test7() { int b[] = {""()}; diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp index b8195950f2fa1..a8e30f1759e9f 100644 --- a/clang/test/AST/ast-dump-recovery.cpp +++ b/clang/test/AST/ast-dump-recovery.cpp @@ -9,28 +9,6 @@ int some_func(int *); // CHECK-NEXT: `-IntegerLiteral {{.*}} 123 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors int invalid_call = some_func(123); -void test_invalid_call_1(int s) { - // CHECK: CallExpr {{.*}} '' contains-errors - // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'some_func' - // CHECK-NEXT: |-RecoveryExpr {{.*}} - // CHECK-NEXT: `-BinaryOperator {{.*}} - // CHECK-NEXT: |-RecoveryExpr {{.*}} - // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1 - some_func(undef1, undef2+1); - - // CHECK: BinaryOperator {{.*}} '' contains-errors '=' - // CHECK-NEXT: |-DeclRefExpr {{.*}} 's' - // CHECK-NEXT: `-CallExpr {{.*}} '' contains-errors - // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'some_func' - // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors - s = some_func(undef1); - - // CHECK: VarDecl {{.*}} var 'int' - // CHECK-NEXT: `-CallExpr {{.*}} '' contains-errors - // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'some_func' - // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors - int var = some_func(undef1); -} int some_func2(int a, int b); void test_invalid_call_2() { @@ -63,22 +41,6 @@ int ambig_func(float); // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors int ambig_call = ambig_func(123); -// CHECK: VarDecl {{.*}} unresolved_call1 -// CHECK-NEXT:`-RecoveryExpr {{.*}} '' contains-errors -// CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'bar' -// DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors -int unresolved_call1 = bar(); - -// CHECK: VarDecl {{.*}} unresolved_call2 -// CHECK-NEXT:`-CallExpr {{.*}} contains-errors -// CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'bar' -// CHECK-NEXT: |-RecoveryExpr {{.*}} contains-errors -// CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 'baz' -// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors -// CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'qux' -// DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors -int unresolved_call2 = bar(baz(), qux()); - constexpr int a = 10; // CHECK: VarDecl {{.*}} postfix_inc @@ -177,11 +139,6 @@ void test2(Foo2 f) { f.overload(1); } -// CHECK: |-AlignedAttr {{.*}} alignas -// CHECK-NEXT:| `-RecoveryExpr {{.*}} contains-errors -// CHECK-NEXT:| `-UnresolvedLookupExpr {{.*}} 'invalid' -struct alignas(invalid()) Aligned {}; - auto f(); int f(double); // CHECK: VarDecl {{.*}} unknown_type_call 'int' @@ -203,16 +160,6 @@ void InvalidInitalizer(int x) { // CHECK-NEXT: `-InitListExpr // CHECK-NEDT: `-DeclRefExpr {{.*}} 'x' Bar a3{x}; - // CHECK: `-VarDecl {{.*}} a4 'Bar' - // CHECK-NEXT: `-ParenListExpr {{.*}} 'NULL TYPE' contains-errors - // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors - // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid' - Bar a4(invalid()); - // CHECK: `-VarDecl {{.*}} a5 'Bar' - // CHECK-NEXT: `-InitListExpr {{.*}} contains-errors - // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors - // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid' - Bar a5{invalid()}; // CHECK: `-VarDecl {{.*}} b1 'Bar' // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors @@ -231,52 +178,12 @@ void InvalidInitalizer(int x) { // CHECK-NEXT: `-InitListExpr {{.*}} 'void' // CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' 'int' Bar b4 = Bar{x}; - // CHECK: `-VarDecl {{.*}} b5 'Bar' - // CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} 'Bar' contains-errors 'Bar' - // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors - // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid' - Bar b5 = Bar(invalid()); - // CHECK: `-VarDecl {{.*}} b6 'Bar' - // CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} 'Bar' contains-errors 'Bar' - // CHECK-NEXT: `-InitListExpr {{.*}} contains-errors - // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors - // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid' - Bar b6 = Bar{invalid()}; // CHECK: RecoveryExpr {{.*}} 'Bar' contains-errors // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1 Bar(1); - - // CHECK: `-VarDecl {{.*}} var1 - // CHECK-NEXT: `-BinaryOperator {{.*}} '' contains-errors - // CHECK-NEXT: |-RecoveryExpr {{.*}} '' contains-errors - // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1 - int var1 = undef + 1; -} -void InitializerForAuto() { - // CHECK: `-VarDecl {{.*}} invalid a 'auto' - // CHECK-NEXT: `-RecoveryExpr {{.*}} '' contains-errors - // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid' - auto a = invalid(); - - // CHECK: `-VarDecl {{.*}} invalid b 'auto' - // CHECK-NEXT: `-CallExpr {{.*}} '' contains-errors - // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'some_func' - // CHECK-NEXT: `-RecoveryExpr {{.*}} '' contains-errors - // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid' - auto b = some_func(invalid()); - - decltype(ned); - // very bad initailizer: there is an unresolved typo expr internally, we just - // drop it. - // CHECK: `-VarDecl {{.*}} invalid unresolved_typo 'auto' - auto unresolved_typo = gned.*[] {}; } -// Verified that the generated call operator is invalid. -// CHECK: |-CXXMethodDecl {{.*}} invalid operator() 'auto () const -> auto' -using Escape = decltype([] { return undef(); }()); - // CHECK: VarDecl {{.*}} NoCrashOnInvalidInitList // CHECK-NEXT: `-RecoveryExpr {{.*}} '' contains-errors lvalue // CHECK-NEXT: `-InitListExpr @@ -301,56 +208,8 @@ void ValueCategory() { xvalue(); // call to a function (rvalue reference return type) yields an xvalue. } -void InvalidCondition() { - // CHECK: IfStmt {{.*}} - // CHECK-NEXT: |-RecoveryExpr {{.*}} '' contains-errors - // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} - if (invalid()) {} - - // CHECK: WhileStmt {{.*}} - // CHECK-NEXT: |-RecoveryExpr {{.*}} '' contains-errors - // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} - while (invalid()) {} - - // CHECK: SwitchStmt {{.*}} - // CHECK-NEXT: |-RecoveryExpr {{.*}} '' contains-errors - // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} - switch(invalid()) { - case 1: - break; - } - // FIXME: figure out why the type of ConditionalOperator is not int. - // CHECK: ConditionalOperator {{.*}} '' contains-errors - // CHECK-NEXT: |-RecoveryExpr {{.*}} '' contains-errors - // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} - // CHECK-NEXT: |-IntegerLiteral {{.*}} 'int' 1 - // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 2 - invalid() ? 1 : 2; -} - void CtorInitializer() { struct S{int m}; - class MemberInit { - int x, y, z; - S s; - MemberInit() : x(invalid), y(invalid, invalid), z(invalid()), s(1,2) {} - // CHECK: CXXConstructorDecl {{.*}} MemberInit 'void ()' - // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 'x' 'int' - // CHECK-NEXT: | `-ParenListExpr - // CHECK-NEXT: | `-RecoveryExpr {{.*}} '' - // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 'y' 'int' - // CHECK-NEXT: | `-ParenListExpr - // CHECK-NEXT: | |-RecoveryExpr {{.*}} '' - // CHECK-NEXT: | `-RecoveryExpr {{.*}} '' - // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 'z' 'int' - // CHECK-NEXT: | `-ParenListExpr - // CHECK-NEXT: | `-RecoveryExpr {{.*}} '' - // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} '' - // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 's' 'S' - // CHECK-NEXT: | `-RecoveryExpr {{.*}} 'S' contains-errors - // CHECK-NEXT: | |-IntegerLiteral {{.*}} 1 - // CHECK-NEXT: | `-IntegerLiteral {{.*}} 2 - }; class BaseInit : S { BaseInit(float) : S("no match") {} // CHECK: CXXConstructorDecl {{.*}} BaseInit 'void (float)' @@ -358,13 +217,6 @@ void CtorInitializer() { // CHECK-NEXT: |-CXXCtorInitializer 'S' // CHECK-NEXT: | `-RecoveryExpr {{.*}} 'S' // CHECK-NEXT: | `-StringLiteral - - BaseInit(double) : S(invalid) {} - // CHECK: CXXConstructorDecl {{.*}} BaseInit 'void (double)' - // CHECK-NEXT: |-ParmVarDecl - // CHECK-NEXT: |-CXXCtorInitializer 'S' - // CHECK-NEXT: | `-ParenListExpr - // CHECK-NEXT: | `-RecoveryExpr {{.*}} '' }; class DelegatingInit { DelegatingInit(float) : DelegatingInit("no match") {} @@ -373,13 +225,6 @@ void CtorInitializer() { // CHECK-NEXT: |-CXXCtorInitializer 'DelegatingInit' // CHECK-NEXT: | `-RecoveryExpr {{.*}} 'DelegatingInit' // CHECK-NEXT: | `-StringLiteral - - DelegatingInit(double) : DelegatingInit(invalid) {} - // CHECK: CXXConstructorDecl {{.*}} DelegatingInit 'void (double)' - // CHECK-NEXT: |-ParmVarDecl - // CHECK-NEXT: |-CXXCtorInitializer 'DelegatingInit' - // CHECK-NEXT: | `-ParenListExpr - // CHECK-NEXT: | `-RecoveryExpr {{.*}} '' }; } @@ -423,65 +268,6 @@ void returnInitListFromVoid() { // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 8 } -void RecoveryExprForInvalidDecls(Unknown InvalidDecl) { - InvalidDecl + 1; - // CHECK: BinaryOperator {{.*}} - // CHECK-NEXT: |-RecoveryExpr {{.*}} '' - // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'InvalidDecl' 'int' - // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1 - InvalidDecl(); - // CHECK: CallExpr {{.*}} - // CHECK-NEXT: `-RecoveryExpr {{.*}} '' -} - -void InitializerOfInvalidDecl() { - int ValidDecl; - Unkown InvalidDecl = ValidDecl; - // CHECK: VarDecl {{.*}} invalid InvalidDecl - // CHECK-NEXT: `-RecoveryExpr {{.*}} '' contains-errors - // CHECK-NEXT: `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'ValidDecl' - - Unknown InvalidDeclWithInvalidInit = Invalid; - // CHECK: VarDecl {{.*}} invalid InvalidDeclWithInvalidInit - // CHECK-NEXT: `-RecoveryExpr {{.*}} '' contains-errors - // CHECK-NOT: `-TypoExpr -} - -void RecoverToAnInvalidDecl() { - Unknown* foo; // invalid decl - goo; // the typo was correct to the invalid foo. - // Verify that RecoveryExpr has an inner DeclRefExpr. - // CHECK: RecoveryExpr {{.*}} '' contains-errors lvalue - // CHECK-NEXT: `-DeclRefExpr {{.*}} 'foo' 'int *' -} - -void RecoveryToDoWhileStmtCond() { - // CHECK: FunctionDecl {{.*}} RecoveryToDoWhileStmtCond - // CHECK: `-DoStmt {{.*}} - // CHECK-NEXT: |-CompoundStmt {{.*}} - // CHECK-NEXT: `-BinaryOperator {{.*}} '' contains-errors '<' - // CHECK-NEXT: |-BinaryOperator {{.*}} '' contains-errors '+' - // CHECK-NEXT: | |-RecoveryExpr {{.*}} '' contains-errors lvalue - // CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 1 - // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 10 - do {} while (some_invalid_val + 1 < 10); -} - -void RecoveryForStmtCond() { - // CHECK:FunctionDecl {{.*}} RecoveryForStmtCond - // CHECK-NEXT:`-CompoundStmt {{.*}} - // CHECK-NEXT: `-ForStmt {{.*}} - // CHECK-NEXT: |-DeclStmt {{.*}} - // CHECK-NEXT: | `-VarDecl {{.*}} - // CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 0 - // CHECK-NEXT: |-<<>> - // CHECK-NEXT: |-RecoveryExpr {{.*}} 'bool' contains-errors - // CHECK-NEXT: |-UnaryOperator {{.*}} 'int' lvalue prefix '++' - // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'i' 'int' - // CHECK-NEXT: `-CompoundStmt {{.*}} - for (int i = 0; i < invalid; ++i) {} -} - // Fix crash issue https://github.com/llvm/llvm-project/issues/112560. // Make sure clang compiles the following code without crashing: diff --git a/clang/test/AST/ast-dump-recovery.m b/clang/test/AST/ast-dump-recovery.m deleted file mode 100644 index 37fa8045c0b94..0000000000000 --- a/clang/test/AST/ast-dump-recovery.m +++ /dev/null @@ -1,32 +0,0 @@ -// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -frecovery-ast-type -fblocks -ast-dump %s | FileCheck -strict-whitespace %s - -@interface Foo -- (void)method:(int)n; -@end - -void k(Foo *foo) { - // CHECK: ObjCMessageExpr {{.*}} 'void' contains-errors - // CHECK-CHECK: |-ImplicitCastExpr {{.*}} 'Foo *' - // CHECK-CHECK: | `-DeclRefExpr {{.*}} 'foo' - // CHECK-CHECK: `-RecoveryExpr {{.*}} - [foo method:undef]; - - // CHECK: ImplicitCastExpr {{.*}} '' contains-errors - // CHECK-NEXT: `-RecoveryExpr {{.*}} '' contains-errors - // CHECK-NEXT: `-DeclRefExpr {{.*}} 'foo' - foo.undef; -} - -// CHECK: |-VarDecl {{.*}} 'int (^)()' cinit -// CHECK-NEXT: | `-RecoveryExpr {{.*}} ' (^)(void)' contains-errors lvalue -// CHECK-NEXT: | `-BlockExpr {{.*}} ' (^)(void)' -// CHECK-NEXT: | `-BlockDecl {{.*}} invalid -int (^gh63863)() = ^() { - return undef; -}; - -// CHECK: `-BlockExpr {{.*}} 'int (^)(int, int)' -// CHECK-NEXT: `-BlockDecl {{.*}} invalid -int (^gh64005)(int, int) = ^(int, undefined b) { - return 1; -}; diff --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp index 8b84de0ab5a9a..c9dce77b772dc 100644 --- a/clang/test/CXX/drs/cwg1xx.cpp +++ b/clang/test/CXX/drs/cwg1xx.cpp @@ -702,8 +702,7 @@ namespace cwg141 { // cwg141: 3.1 // cxx98-error@#cwg141-a {{lookup of 'S' in member access expression is ambiguous; using member of 'struct A'}} // cxx98-note@#cwg141-A-S {{lookup in the object type 'struct A' refers here}} // cxx98-note@#cwg141-S {{lookup from the current scope refers here}} - // expected-error@#cwg141-a {{no member named 'n' in 'cwg141::A::S'; did you mean '::cwg141::S::n'?}} - // expected-note@#cwg141-S {{'::cwg141::S::n' declared here}} + // expected-error@#cwg141-a {{no member named 'n' in 'cwg141::A::S'}} // FIXME: we issue a useful diagnostic first, then some bogus ones. b.f(); // expected-error@-1 {{no member named 'f' in 'cwg141::B'}} diff --git a/clang/test/CXX/drs/cwg26xx.cpp b/clang/test/CXX/drs/cwg26xx.cpp index ab4d3695b6e22..60d896443ecd1 100644 --- a/clang/test/CXX/drs/cwg26xx.cpp +++ b/clang/test/CXX/drs/cwg26xx.cpp @@ -220,7 +220,6 @@ int x = cwg2640_a\N{abc}); int y = cwg2640_a\N{LOTUS}); // expected-error@-1 {{character not allowed in an identifier}} // expected-error@-2 {{use of undeclared identifier 'cwg2640_a🪷'}} -// expected-error@-3 {{extraneous ')' before ';'}} } // namespace cwg2640 // cwg2642: na diff --git a/clang/test/CXX/module/basic/basic.link/p2.cppm b/clang/test/CXX/module/basic/basic.link/p2.cppm index d7d2b5992a235..6a2c67526c9a1 100644 --- a/clang/test/CXX/module/basic/basic.link/p2.cppm +++ b/clang/test/CXX/module/basic/basic.link/p2.cppm @@ -51,7 +51,7 @@ void use_from_module_impl() { (void)external_linkage_var; (void)module_linkage_var; - (void)internal_linkage_class{}; // expected-error {{use of undeclared identifier 'internal_linkage_class'}} //expected-error{{}} + (void)internal_linkage_class{}; // expected-error {{use of undeclared identifier 'internal_linkage_class'}} // expected-note@* {{}} (void)internal_linkage_var; // expected-error {{use of undeclared identifier 'internal_linkage_var'}} } @@ -64,7 +64,7 @@ void use_from_module_impl() { internal_linkage_fn(); // expected-error {{use of undeclared identifier 'internal_linkage_fn'}} (void)external_linkage_class{}; (void)module_linkage_class{}; // expected-error {{undeclared identifier}} expected-error 0+{{}} // expected-note@* {{}} - (void)internal_linkage_class{}; // expected-error {{undeclared identifier}} expected-error 0+{{}} + (void)internal_linkage_class{}; // expected-error {{undeclared identifier}} expected-error 0+{{}} // expected-note@* {{}} (void)external_linkage_var; (void)module_linkage_var; // expected-error {{undeclared identifier}} (void)internal_linkage_var; // expected-error {{undeclared identifier}} diff --git a/clang/test/FixIt/typo.cpp b/clang/test/FixIt/typo.cpp deleted file mode 100644 index e489fbbcaa1df..0000000000000 --- a/clang/test/FixIt/typo.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -// RUN: cp %s %t -// RUN: not %clang_cc1 -fixit -x c++ %t -// RUN: %clang_cc1 -fsyntax-only -pedantic -Werror -x c++ %t -// RUN: grep test_string %t - -namespace std { - template class basic_string { // expected-note 3{{'basic_string' declared here}} - public: - int find(const char *substr); // expected-note{{'find' declared here}} - static const int npos = -1; // expected-note{{'npos' declared here}} - }; - - typedef basic_string string; // expected-note 2{{'string' declared here}} -} - -namespace otherstd { // expected-note 2{{'otherstd' declared here}} \ - // expected-note{{namespace 'otherstd' defined here}} - using namespace std; -} - -using namespace std; - -other_std::strng str1; // expected-error{{use of undeclared identifier 'other_std'; did you mean 'otherstd'?}} \ -// expected-error{{no type named 'strng' in namespace 'otherstd'; did you mean 'string'?}} -tring str2; // expected-error{{unknown type name 'tring'; did you mean 'string'?}} - -::other_std::string str3; // expected-error{{no member named 'other_std' in the global namespace; did you mean 'otherstd'?}} - -float area(float radius, // expected-note{{'radius' declared here}} - float pi) { - return radious * pi; // expected-error{{did you mean 'radius'?}} -} - -using namespace othestd; // expected-error{{no namespace named 'othestd'; did you mean 'otherstd'?}} -namespace blargh = otherstd; // expected-note 3{{namespace 'blargh' defined here}} -using namespace ::blarg; // expected-error{{no namespace named 'blarg' in the global namespace; did you mean 'blargh'?}} - -namespace wibble = blarg; // expected-error{{no namespace named 'blarg'; did you mean 'blargh'?}} -namespace wobble = ::blarg; // expected-error{{no namespace named 'blarg' in the global namespace; did you mean 'blargh'?}} - -bool test_string(std::string s) { - basc_string b1; // expected-error{{no template named 'basc_string'; did you mean 'basic_string'?}} - std::basic_sting b2; // expected-error{{no template named 'basic_sting' in namespace 'std'; did you mean 'basic_string'?}} - (void)b1; - (void)b2; - return s.fnd("hello") // expected-error{{no member named 'fnd' in 'std::basic_string'; did you mean 'find'?}} - == std::string::pos; // expected-error{{no member named 'pos' in 'std::basic_string'; did you mean 'npos'?}} -} - -struct Base { }; -struct Derived : public Base { // expected-note{{base class 'Base' specified here}} - int member; // expected-note 3{{'member' declared here}} - - Derived() : base(), // expected-error{{initializer 'base' does not name a non-static data member or base class; did you mean the base class 'Base'?}} - ember() { } // expected-error{{initializer 'ember' does not name a non-static data member or base class; did you mean the member 'member'?}} - - int getMember() const { - return ember; // expected-error{{use of undeclared identifier 'ember'; did you mean 'member'?}} - } - - int &getMember(); -}; - -int &Derived::getMember() { - return ember; // expected-error{{use of undeclared identifier 'ember'; did you mean 'member'?}} -} - -typedef int Integer; // expected-note{{'Integer' declared here}} -int global_value; // expected-note{{'global_value' declared here}} - -int foo() { - integer * i = 0; // expected-error{{unknown type name 'integer'; did you mean 'Integer'?}} - unsinged *ptr = 0; // expected-error{{use of undeclared identifier 'unsinged'; did you mean 'unsigned'?}} - return *i + *ptr + global_val; // expected-error{{use of undeclared identifier 'global_val'; did you mean 'global_value'?}} -} - -namespace nonstd { - typedef std::basic_string yarn; // expected-note 2 {{'nonstd::yarn' declared here}} - int narf; // expected-note{{'nonstd::narf' declared here}} -} - -yarn str4; // expected-error{{unknown type name 'yarn'; did you mean 'nonstd::yarn'?}} -wibble::yarn str5; // expected-error{{no type named 'yarn' in namespace 'otherstd'; did you mean 'nonstd::yarn'?}} - -namespace another { - template class wide_string {}; // expected-note {{'another::wide_string' declared here}} -} -int poit() { - nonstd::basic_string str; // expected-error{{no template named 'basic_string' in namespace 'nonstd'; did you mean simply 'basic_string'?}} - nonstd::wide_string str2; // expected-error{{no template named 'wide_string' in namespace 'nonstd'; did you mean 'another::wide_string'?}} - return wibble::narf; // expected-error{{no member named 'narf' in namespace 'otherstd'; did you mean 'nonstd::narf'?}} -} - -namespace check_bool { - void f() { - Bool b; // expected-error{{use of undeclared identifier 'Bool'; did you mean 'bool'?}} - } -} - -namespace outr { -} -namespace outer { - namespace inner { // expected-note{{'outer::inner' declared here}} \ - // expected-note{{namespace 'outer::inner' defined here}} \ - // expected-note{{'inner' declared here}} - int i; - } -} - -using namespace outr::inner; // expected-error{{no namespace named 'inner' in namespace 'outr'; did you mean 'outer::inner'?}} - -void func() { - outr::inner::i = 3; // expected-error{{no member named 'inner' in namespace 'outr'; did you mean 'outer::inner'?}} - outer::innr::i = 4; // expected-error{{no member named 'innr' in namespace 'outer'; did you mean 'inner'?}} -} - -struct base { -}; -struct derived : base { - int i; -}; - -void func2() { - derived d; - // FIXME: we should offer a fix here. We do if the 'i' is misspelled, but we don't do name qualification changes - // to replace base::i with derived::i as we would for other qualified name misspellings. - // d.base::i = 3; -} - -class A { - void bar(int); -}; -void bar(int, int); // expected-note{{'::bar' declared here}} -void A::bar(int x) { - bar(x, 5); // expected-error{{too many arguments to function call, expected 1, have 2; did you mean '::bar'?}} -} diff --git a/clang/test/Index/complete-switch.c b/clang/test/Index/complete-switch.c deleted file mode 100644 index 4a78854595543..0000000000000 --- a/clang/test/Index/complete-switch.c +++ /dev/null @@ -1,10 +0,0 @@ -void f() { - auto foo = bar; - switch(foo) { - case x: - break; - } -} - -// RUN: not %clang_cc1 -fsyntax-only -fno-recovery-ast -code-completion-at=%s:4:10 %s | FileCheck %s -allow-empty -// CHECK-NOT: COMPLETION: foo diff --git a/clang/test/Index/fix-its.c b/clang/test/Index/fix-its.c index 1e710c28afcca..8378fd9da9b43 100644 --- a/clang/test/Index/fix-its.c +++ b/clang/test/Index/fix-its.c @@ -1,27 +1,12 @@ -// RUN: c-index-test -test-load-source all -fspell-checking %s 2> %t +// RUN: c-index-test -test-load-source all -fspell-checking %s 2> %t // RUN: FileCheck %s < %t -struct X { - int wibble; -}; - #define MACRO(X) X -void f(struct X *x) { - // CHECK: error: no member named 'wobble' in 'struct X'; did you mean 'wibble'? - // CHECK: FIX-IT: Replace [13:12 - 13:18] with "wibble" - // CHECK: note: 'wibble' declared here - MACRO(x->wobble = 17); - // CHECK: error: no member named 'wabble' in 'struct X'; did you mean 'wibble'? - // CHECK: FIX-IT: Replace [17:6 - 17:12] with "wibble" - // CHECK: note: 'wibble' declared here - x->wabble = 17; -} - int printf(const char *restrict, ...); void f2() { unsigned long index; // CHECK: warning: format specifies type 'int' but the argument has type 'unsigned long' - // CHECK: FIX-IT: Replace [26:17 - 26:19] with "%lu" + // CHECK: FIX-IT: Replace [11:17 - 11:19] with "%lu" MACRO(printf("%d", index)); } diff --git a/clang/test/Lexer/raw-string-ext.c b/clang/test/Lexer/raw-string-ext.c index de318b616df70..8ed96e5c19f0d 100644 --- a/clang/test/Lexer/raw-string-ext.c +++ b/clang/test/Lexer/raw-string-ext.c @@ -27,13 +27,13 @@ // no-warning@* {{ignoring '-fno-raw-string-literals'}} void f() { - (void) R"foo()foo"; // unsupported-error {{use of undeclared identifier 'R'}} cxx-unsupported-error {{expected ';' after expression}} - (void) LR"foo()foo"; // unsupported-error {{use of undeclared identifier 'LR'}} cxx-unsupported-error {{expected ';' after expression}} + (void) R"foo()foo"; // unsupported-error {{use of undeclared identifier 'R'}} + (void) LR"foo()foo"; // unsupported-error {{use of undeclared identifier 'LR'}} #ifdef UNICODE - (void) uR"foo()foo"; // unsupported-error {{use of undeclared identifier 'uR'}} cxx-unsupported-error {{expected ';' after expression}} - (void) u8R"foo()foo"; // unsupported-error {{use of undeclared identifier 'u8R'}} cxx-unsupported-error {{expected ';' after expression}} - (void) UR"foo()foo"; // unsupported-error {{use of undeclared identifier 'UR'}} cxx-unsupported-error {{expected ';' after expression}} + (void) uR"foo()foo"; // unsupported-error {{use of undeclared identifier 'uR'}} + (void) u8R"foo()foo"; // unsupported-error {{use of undeclared identifier 'u8R'}} + (void) UR"foo()foo"; // unsupported-error {{use of undeclared identifier 'UR'}} #endif } diff --git a/clang/test/Modules/diagnose-missing-import.m b/clang/test/Modules/diagnose-missing-import.m index 8fb8e6b25f68a..b34bc1a62b6bc 100644 --- a/clang/test/Modules/diagnose-missing-import.m +++ b/clang/test/Modules/diagnose-missing-import.m @@ -7,11 +7,9 @@ void foo(void) { XYZLogEvent(xyzRiskyCloseOpenParam, xyzRiskyCloseOpenParam); // expected-error {{call to undeclared function 'XYZLogEvent'; ISO C99 and later do not support implicit function declarations}} \ expected-error {{declaration of 'XYZLogEvent' must be imported}} \ - expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}} \ expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}} } -// expected-note@Inputs/diagnose-missing-import/a.h:5 {{declaration here is not visible}} // expected-note@Inputs/diagnose-missing-import/a.h:5 {{declaration here is not visible}} // expected-note@Inputs/diagnose-missing-import/a.h:6 {{declaration here is not visible}} diff --git a/clang/test/OpenMP/begin_declare_variant_messages.c b/clang/test/OpenMP/begin_declare_variant_messages.c index d8d8f4211678f..8878188e7ceb2 100644 --- a/clang/test/OpenMP/begin_declare_variant_messages.c +++ b/clang/test/OpenMP/begin_declare_variant_messages.c @@ -83,7 +83,7 @@ const int var; #pragma omp end declare variant #pragma omp begin declare variant match(device={kind(score cpu)}) // expected-error {{expected '(' after 'score'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score (''); score ignored}} #pragma omp end declare variant -#pragma omp begin declare variant match(device = {kind(score(ibm) }) // expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('()'); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}} +#pragma omp begin declare variant match(device = {kind(score(ibm) }) // expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score (''); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}} #pragma omp end declare variant #pragma omp begin declare variant match(device={kind(score(2 gpu)}) // expected-error {{expected ')'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('2'); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{to match this '('}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}} #pragma omp end declare variant diff --git a/clang/test/OpenMP/declare_reduction_messages.cpp b/clang/test/OpenMP/declare_reduction_messages.cpp index 752cc4fb05a12..f91d952dfa14f 100644 --- a/clang/test/OpenMP/declare_reduction_messages.cpp +++ b/clang/test/OpenMP/declare_reduction_messages.cpp @@ -69,7 +69,7 @@ class Class2 : public Class1 { #pragma omp declare reduction(fun77 : long : omp_out += omp_in) initializer(omp_priv Class2 < int > ()) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp declare reduction(fun8 : long : omp_out += omp_in) initializer(omp_priv 23) // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp declare reduction(fun88 : long : omp_out += omp_in) initializer(omp_priv 23)) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} -#pragma omp declare reduction(fun9 : long : omp_out += omp_priv) initializer(omp_in = 23) // expected-error {{use of undeclared identifier 'omp_priv'; did you mean 'omp_in'?}} expected-note {{'omp_in' declared here}} +#pragma omp declare reduction(fun9 : long : omp_out += omp_priv) initializer(omp_in = 23) // expected-error {{use of undeclared identifier 'omp_priv'}} #pragma omp declare reduction(fun10 : long : omp_out += omp_in) initializer(omp_priv = 23) template diff --git a/clang/test/OpenMP/declare_variant_messages.c b/clang/test/OpenMP/declare_variant_messages.c index 32e365cc415bd..d1e36e5d1e7e9 100644 --- a/clang/test/OpenMP/declare_variant_messages.c +++ b/clang/test/OpenMP/declare_variant_messages.c @@ -11,7 +11,7 @@ int foo(void); #pragma omp declare variant // expected-error {{expected '(' after 'declare variant'}} #pragma omp declare variant( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp declare variant(foo // expected-error {{expected ')'}} omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} expected-note {{to match this '('}} -#pragma omp declare variant(x) // expected-error {{use of undeclared identifier 'x'}} omp50-error {{expected 'match' clause on}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} +#pragma omp declare variant(x) // expected-error {{use of undeclared identifier 'x'}} #pragma omp declare variant(foo) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} #pragma omp declare variant(foo) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} #pragma omp declare variant(foo) xxx // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} @@ -42,7 +42,7 @@ int foo(void); #pragma omp declare variant(foo) match(device={kind(}) // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}} #pragma omp declare variant(foo) match(device={kind()}) // expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} #pragma omp declare variant(foo) match(device={kind(score cpu)}) // expected-error {{expected '(' after 'score'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score (''); score ignored}} -#pragma omp declare variant(foo) match(device = {kind(score(ibm) }) // expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('()'); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}} +#pragma omp declare variant(foo) match(device = {kind(score(ibm) }) // expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score (''); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}} #pragma omp declare variant(foo) match(device={kind(score(2 gpu)}) // expected-error {{expected ')'}} expected-error {{expected ')'}} expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('2'); score ignored}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{to match this '('}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}} #pragma omp declare variant(foo) match(device={kind(score(foo()) ibm)}) // expected-warning {{expected '':'' after the score expression; '':'' assumed}} expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('foo()'); score ignored}} expected-warning {{'ibm' is not a valid context property for the context selector 'kind' and the context set 'device'; property ignored}} expected-note {{try 'match(implementation={vendor(ibm)})'}} expected-note {{the ignored property spans until here}} #pragma omp declare variant(foo) match(device={kind(score(5): host), kind(llvm)}) // expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('5'); score ignored}} expected-warning {{the context selector 'kind' was used already in the same 'omp declare variant' directive; selector ignored}} expected-note {{the previous context selector 'kind' used here}} expected-note {{the ignored selector spans until here}} @@ -56,7 +56,7 @@ int foo(void); #pragma omp declare variant(foo) match(target_device={device_num}) // expected-warning {{the context selector 'device_num' in context set 'target_device' requires a context property defined in parentheses; selector ignored}} expected-note {{the ignored selector spans until here}} #pragma omp declare variant(foo) match(target_device={device_num()}) // expected-error {{expected expression}} #pragma omp declare variant(foo) match(target_device={device_num(-1)}) // expected-error {{argument to 'device_num' clause must be a non-negative integer value}} -#pragma omp declare variant(foo) match(target_device={device_num(abc)}) // expected-error {{expected expression}} expected-error {{use of undeclared identifier 'abc'}} +#pragma omp declare variant(foo) match(target_device={device_num(abc)}) // expected-error {{use of undeclared identifier 'abc'}} int bar(void); diff --git a/clang/test/OpenMP/declare_variant_messages.cpp b/clang/test/OpenMP/declare_variant_messages.cpp index 8eb37bc64cbc1..06da8a8e5b058 100644 --- a/clang/test/OpenMP/declare_variant_messages.cpp +++ b/clang/test/OpenMP/declare_variant_messages.cpp @@ -16,7 +16,7 @@ T foofoo(); #pragma omp declare variant // expected-error {{expected '(' after 'declare variant'}} #pragma omp declare variant( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp declare variant(foo // expected-error {{expected ')'}} omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} expected-note {{to match this '('}} -#pragma omp declare variant(x) // expected-error {{use of undeclared identifier 'x'}} omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} +#pragma omp declare variant(x) // expected-error {{use of undeclared identifier 'x'}} #pragma omp declare variant(foo) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} #pragma omp declare variant(foofoo ) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} #pragma omp declare variant(foofoo ) xxx // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} @@ -57,7 +57,7 @@ int bar(); #pragma omp declare variant // expected-error {{expected '(' after 'declare variant'}} #pragma omp declare variant( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp declare variant(foofoo // expected-error {{expected ')'}} omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} expected-note {{to match this '('}} -#pragma omp declare variant(x) // expected-error {{use of undeclared identifier 'x'}} omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} +#pragma omp declare variant(x) // expected-error {{use of undeclared identifier 'x'}} #pragma omp declare variant(foo) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} #pragma omp declare variant(foofoo) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} #pragma omp declare variant(foofoo ) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} diff --git a/clang/test/OpenMP/target_update_messages.cpp b/clang/test/OpenMP/target_update_messages.cpp index 83191059202ca..000cc80e513e6 100644 --- a/clang/test/OpenMP/target_update_messages.cpp +++ b/clang/test/OpenMP/target_update_messages.cpp @@ -113,9 +113,11 @@ int main(int argc, char **argv) { // Check parsing with two modifiers. // lt51-warning@+1 {{missing ':' after ) - ignoring}} #pragma omp target update to(mapper(id), present: s) - // lt51-error@+3 {{use of undeclared identifier 'present'}} - // lt51-error@+2 {{use of undeclared identifier 'id'}} - // lt51-error@+1 {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + // lt51-error@+5 {{use of undeclared identifier 'present'}} + // lt51-error@+4 {{use of undeclared identifier 'id'}} + // lt51-error@+3 {{expected ',' or ')' in 'to' clause}} + // lt51-error@+2 {{expected ')'}} + // lt51-note@+1 {{to match this '('}} #pragma omp target update to(present, mapper(id): s) // lt51-warning@+1 {{missing ':' after ) - ignoring}} #pragma omp target update to(mapper(id) present: s) @@ -141,10 +143,9 @@ int main(int argc, char **argv) { #pragma omp target update to(present,,: s) // lt51-warning@+1 {{missing ':' after ) - ignoring}} #pragma omp target update to(mapper(id), present,: s) - // lt51-error@+4 {{use of undeclared identifier 'present'}} - // lt51-error@+3 {{use of undeclared identifier 'id'}} - // lt51-error@+2 {{expected expression}} - // lt51-error@+1 {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + // lt51-error@+3 {{use of undeclared identifier 'present'}} + // lt51-error@+2 {{use of undeclared identifier 'id'}} + // lt51-error@+1 {{expected expression}} #pragma omp target update to(present, mapper(id),: s) #pragma omp target update from(m) allocate(m) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp target update'}} diff --git a/clang/test/Parser/cxx1z-decomposition.cpp b/clang/test/Parser/cxx1z-decomposition.cpp index 3e2526979be8b..b7a8d30bd16c5 100644 --- a/clang/test/Parser/cxx1z-decomposition.cpp +++ b/clang/test/Parser/cxx1z-decomposition.cpp @@ -3,7 +3,7 @@ // RUN: %clang_cc1 -std=c++2c %s -triple x86_64-unknown-linux-gnu -verify=expected,cxx2c,post2b -fcxx-exceptions // RUN: not %clang_cc1 -std=c++17 %s -triple x86_64-unknown-linux-gnu -emit-llvm-only -fcxx-exceptions -struct S { int a, b, c; }; +struct S { int a, b, c; }; // expected-note 2 {{'S::a' declared here}} // A simple-declaration can be a decompsition declaration. namespace SimpleDecl { @@ -32,7 +32,7 @@ namespace ForRangeDecl { namespace OtherDecl { // A parameter-declaration is not a simple-declaration. // This parses as an array declaration. - void f(auto [a, b, c]); // cxx17-error {{'auto' not allowed in function prototype}} expected-error {{'a'}} + void f(auto [a, b, c]); // cxx17-error {{'auto' not allowed in function prototype}} expected-error 1+{{'a'}} void g() { // A condition is allowed as a Clang extension. @@ -46,7 +46,7 @@ namespace OtherDecl { // An exception-declaration is not a simple-declaration. try {} - catch (auto [a, b, c]) {} // expected-error {{'auto' not allowed in exception declaration}} expected-error {{'a'}} + catch (auto [a, b, c]) {} // expected-error {{'auto' not allowed in exception declaration}} expected-error 1+{{'a'}} } // A member-declaration is not a simple-declaration. diff --git a/clang/test/Parser/cxx1z-fold-expressions.cpp b/clang/test/Parser/cxx1z-fold-expressions.cpp index 4a329646b799f..d798a9cbb99b7 100644 --- a/clang/test/Parser/cxx1z-fold-expressions.cpp +++ b/clang/test/Parser/cxx1z-fold-expressions.cpp @@ -37,14 +37,14 @@ template int bad12() { return (... N); } // expected-error {{expected template void as_operand_of_cast(int a, T ...t) { return - (int)(a + ... + undeclared_junk) + // expected-error {{undeclared}} expected-error {{does not contain any unexpanded}} + (int)(a + ... + undeclared_junk) + // expected-error {{undeclared}} (int)(t + ... + undeclared_junk) + // expected-error {{undeclared}} - (int)(... + undeclared_junk) + // expected-error {{undeclared}} expected-error {{does not contain any unexpanded}} + (int)(... + undeclared_junk) + // expected-error {{undeclared}} (int)(undeclared_junk + ...) + // expected-error {{undeclared}} (int)(a + ...) + // expected-error {{does not contain any unexpanded}} (int)(a, ...) + // expected-error {{does not contain any unexpanded}} (int)(..., a) + // expected-error {{does not contain any unexpanded}} - (int)(a, ..., undeclared_junk) + // expected-error {{undeclared}} expected-error {{does not contain any unexpanded}} + (int)(a, ..., undeclared_junk) + // expected-error {{undeclared}} (int)(t, ...) + (int)(..., t) + (int)(t, ..., a); diff --git a/clang/test/Parser/cxx2c-pack-indexing.cpp b/clang/test/Parser/cxx2c-pack-indexing.cpp index 72e286322fa97..79069a86ea706 100644 --- a/clang/test/Parser/cxx2c-pack-indexing.cpp +++ b/clang/test/Parser/cxx2c-pack-indexing.cpp @@ -69,7 +69,8 @@ template requires( ); // expected-error {{expected expression}} struct SS { void f( ) { - (*p).~T...[](); // expected-error {{use of undeclared identifier 'p'}} + (*p).~T...[](); // expected-error {{use of undeclared identifier 'p'}} \ + expected-error {{undeclared identifier 'T' in destructor name}} } }; } diff --git a/clang/test/Parser/objc-foreach-syntax.m b/clang/test/Parser/objc-foreach-syntax.m index 2158d8062f6cd..1ff84f393b9f4 100644 --- a/clang/test/Parser/objc-foreach-syntax.m +++ b/clang/test/Parser/objc-foreach-syntax.m @@ -21,6 +21,5 @@ - (void)compilerTestAgainst { static int test7(id keys) { - for (id key; in keys) ; // expected-error {{use of undeclared identifier 'in'}} \ - // expected-error {{expected ';' in 'for' statement specifier}} + for (id key; in keys) ; // expected-error {{use of undeclared identifier 'in'}} } diff --git a/clang/test/Parser/opencl-atomics-cl20.cl b/clang/test/Parser/opencl-atomics-cl20.cl index 2648142f28e7c..2cd2c6ca133e1 100644 --- a/clang/test/Parser/opencl-atomics-cl20.cl +++ b/clang/test/Parser/opencl-atomics-cl20.cl @@ -39,23 +39,17 @@ void atomic_types_test(void) { // expected-error@-11 {{use of undeclared identifier 'atomic_ulong'}} // expected-error@-11 {{use of undeclared identifier 'atomic_double'}} #if defined(LANG_VER_OK) -// expected-error@-15 {{expected ';' after expression}} -// expected-error@-16 {{use of undeclared identifier 'l'}} -// expected-error@-16 {{expected ';' after expression}} -// expected-error@-17 {{use of undeclared identifier 'ul'}} #endif #if !defined(LANG_VER_OK) || defined(__SPIR64__) -// expected-error@-18 {{use of undeclared identifier 'atomic_size_t'}} -// expected-error@-16 {{use of undeclared identifier 'atomic_ptrdiff_t'}} +// expected-error@-14 {{use of undeclared identifier 'atomic_size_t'}} +// expected-error@-12 {{use of undeclared identifier 'atomic_ptrdiff_t'}} #if !defined(LANG_VER_OK) -// expected-error@-20 {{use of undeclared identifier 'atomic_intptr_t'}} -// expected-error@-20 {{use of undeclared identifier 'atomic_uintptr_t'}} +// expected-error@-16 {{use of undeclared identifier 'atomic_intptr_t'}} +// expected-error@-16 {{use of undeclared identifier 'atomic_uintptr_t'}} #else -// expected-error@-24 {{expected ';' after expression}} -// expected-error@-25 {{use of undeclared identifier 's'}} -// expected-error@-25 {{unknown type name 'atomic_intptr_t'; did you mean 'atomic_int'?}} +// expected-error@-19 {{unknown type name 'atomic_intptr_t'; did you mean 'atomic_int'?}} // expected-note@* {{'atomic_int' declared here}} -// expected-error@-26 {{unknown type name 'atomic_uintptr_t'; did you mean 'atomic_uint'?}} +// expected-error@-20 {{unknown type name 'atomic_uintptr_t'; did you mean 'atomic_uint'?}} // expected-note@* {{'atomic_uint' declared here}} #endif #endif diff --git a/clang/test/Parser/recovery.c b/clang/test/Parser/recovery.c index 6fdbedffd236a..0d86bd0608bf1 100644 --- a/clang/test/Parser/recovery.c +++ b/clang/test/Parser/recovery.c @@ -11,7 +11,7 @@ float test2241[2] = { static void f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; // expected-error {{identifier}} - s = g (p, __builtin_va_arg(v, int)); // expected-error {{identifier}} + s = g (p, __builtin_va_arg(v, int)); // expected-error {{identifier}} expected-error {{extraneous ')' before ';'}} } diff --git a/clang/test/Parser/switch-recovery.cpp b/clang/test/Parser/switch-recovery.cpp index baf703cd03aed..a0c33ce943fbe 100644 --- a/clang/test/Parser/switch-recovery.cpp +++ b/clang/test/Parser/switch-recovery.cpp @@ -104,7 +104,7 @@ void test9(int x) { // expected-note {{'x' declared here}} expected-error {{expected expression}} 8:: x; // expected-error {{expected ';' after expression}} \ expected-error {{no member named 'x' in the global namespace; did you mean simply 'x'?}} \ - expected-warning {{expression result unused}} + expected-warning 2 {{expression result unused}} 9:: :y; // expected-error {{expected ';' after expression}} \ expected-error {{expected unqualified-id}} \ expected-warning {{expression result unused}} diff --git a/clang/test/Parser/switch-typo-correction.cpp b/clang/test/Parser/switch-typo-correction.cpp index ebf1c18f2b86a..95d610b9cdd25 100644 --- a/clang/test/Parser/switch-typo-correction.cpp +++ b/clang/test/Parser/switch-typo-correction.cpp @@ -1,9 +1,9 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -namespace c { double xxx; } // expected-note{{'c::xxx' declared here}} +namespace c { double xxx; } namespace d { float xxx; } namespace z { namespace xxx {} } void crash() { - switch (xxx) {} // expected-error{{use of undeclared identifier 'xxx'; did you mean }} + switch (xxx) {} // expected-error{{use of undeclared identifier 'xxx'}} } diff --git a/clang/test/ParserOpenACC/parse-cache-construct.cpp b/clang/test/ParserOpenACC/parse-cache-construct.cpp index a5a1e58028c33..948f2e30f149c 100644 --- a/clang/test/ParserOpenACC/parse-cache-construct.cpp +++ b/clang/test/ParserOpenACC/parse-cache-construct.cpp @@ -1,8 +1,8 @@ // RUN: %clang_cc1 %s -verify -fopenacc namespace NS { - static char* NSArray;// expected-note{{declared here}} - static int NSInt;// expected-note 2{{declared here}} + static char* NSArray; // expected-note {{'NS::NSArray' declared here}} + static int NSInt; // expected-note 2 {{'NS::NSInt' declared here}} } char *getArrayPtr(); template @@ -21,17 +21,17 @@ void func() { } for (int i = 0; i < 10; ++i) { - // expected-error@+1{{use of undeclared identifier 'NSArray'; did you mean 'NS::NSArray'}} + // expected-error@+1{{use of undeclared identifier 'NSArray'}} #pragma acc cache(NSArray[NS::NSInt : NS::NSInt]) } for (int i = 0; i < 10; ++i) { - // expected-error@+1{{use of undeclared identifier 'NSInt'; did you mean 'NS::NSInt'}} + // expected-error@+1{{use of undeclared identifier 'NSInt'}} #pragma acc cache(NS::NSArray[NSInt : NS::NSInt]) } for (int i = 0; i < 10; ++i) { - // expected-error@+1{{use of undeclared identifier 'NSInt'; did you mean 'NS::NSInt'}} + // expected-error@+1{{use of undeclared identifier 'NSInt'}} #pragma acc cache(NS::NSArray[NS::NSInt : NSInt]) } } diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c index 6d771e858d243..a9ad7ab176cbc 100644 --- a/clang/test/ParserOpenACC/parse-clauses.c +++ b/clang/test/ParserOpenACC/parse-clauses.c @@ -347,9 +347,7 @@ void SelfUpdate() { #pragma acc update host(s) self for(int i = 0; i < 5;++i) {} - // expected-error@+3{{use of undeclared identifier 'zero'}} - // expected-error@+2{{expected ','}} - // expected-error@+1{{expected expression}} + // expected-error@+1{{use of undeclared identifier 'zero'}} #pragma acc update self(zero : s.array[s.value : 5], s.value), if_present for(int i = 0; i < 5;++i) {} @@ -453,8 +451,6 @@ void VarListClauses() { #pragma acc parallel copy(always, alwaysin, always: HasMem.MemArr[3:]) self for(int i = 0; i < 5;++i) {} - // expected-error@+3{{use of undeclared identifier 'always'}} - // expected-error@+2{{use of undeclared identifier 'alwaysin'}} // expected-error@+1{{use of undeclared identifier 'always'}} #pragma acc parallel copy(always, alwaysin, always, HasMem.MemArr[3:]) self for(int i = 0; i < 5;++i) {} @@ -591,8 +587,7 @@ void VarListClauses() { #pragma acc serial copyout(zero : s.array[s.value : 5], s.value), self for(int i = 0; i < 5;++i) {} - // expected-error@+2{{use of undeclared identifier 'zero'}} - // expected-error@+1{{expected ','}} + // expected-error@+1{{use of undeclared identifier 'zero'}} #pragma acc serial copyout(zero s.array[s.value : 5], s.value), self for(int i = 0; i < 5;++i) {} @@ -608,8 +603,7 @@ void VarListClauses() { #pragma acc serial copyout(invalid:s.array[s.value : 5], s.value), self for(int i = 0; i < 5;++i) {} - // expected-error@+2{{use of undeclared identifier 'invalid'}} - // expected-error@+1{{expected ','}} + // expected-error@+1{{use of undeclared identifier 'invalid'}} #pragma acc serial copyout(invalid s.array[s.value : 5], s.value), self for(int i = 0; i < 5;++i) {} @@ -657,8 +651,7 @@ void VarListClauses() { #pragma acc serial create(zero : s.array[s.value : 5], s.value), self for(int i = 0; i < 5;++i) {} - // expected-error@+2{{use of undeclared identifier 'zero'}} - // expected-error@+1{{expected ','}} + // expected-error@+1{{use of undeclared identifier 'zero'}} #pragma acc serial create(zero s.array[s.value : 5], s.value), self for(int i = 0; i < 5;++i) {} @@ -674,8 +667,7 @@ void VarListClauses() { #pragma acc serial create(invalid:s.array[s.value : 5], s.value), self for(int i = 0; i < 5;++i) {} - // expected-error@+2{{use of undeclared identifier 'invalid'}} - // expected-error@+1{{expected ','}} + // expected-error@+1{{use of undeclared identifier 'invalid'}} #pragma acc serial create(invalid s.array[s.value : 5], s.value), self for(int i = 0; i < 5;++i) {} @@ -700,8 +692,7 @@ void VarListClauses() { #pragma acc serial copyin(readonly : s.array[s.value : 5], s.value), self for(int i = 0; i < 5;++i) {} - // expected-error@+2{{use of undeclared identifier 'readonly'}} - // expected-error@+1{{expected ','}} + // expected-error@+1{{use of undeclared identifier 'readonly'}} #pragma acc serial copyin(readonly s.array[s.value : 5], s.value), self for(int i = 0; i < 5;++i) {} @@ -717,8 +708,7 @@ void VarListClauses() { #pragma acc serial copyin(invalid:s.array[s.value : 5], s.value), self for(int i = 0; i < 5;++i) {} - // expected-error@+2{{use of undeclared identifier 'invalid'}} - // expected-error@+1{{expected ','}} + // expected-error@+1{{use of undeclared identifier 'invalid'}} #pragma acc serial copyin(invalid s.array[s.value : 5], s.value), self for(int i = 0; i < 5;++i) {} diff --git a/clang/test/ParserOpenACC/parse-constructs.cpp b/clang/test/ParserOpenACC/parse-constructs.cpp index 814f6a1fd09f2..69b04bcbad9e3 100644 --- a/clang/test/ParserOpenACC/parse-constructs.cpp +++ b/clang/test/ParserOpenACC/parse-constructs.cpp @@ -18,13 +18,13 @@ namespace NS { #pragma acc routine(NS::foo) seq // expected-error@+2{{use of undeclared identifier 'templ'; did you mean 'NS::templ'?}} -// expected-error@+1{{OpenACC routine name 'NS::templ' names a set of overloads}} +// expected-error@+1{{OpenACC routine name 'templ' names a set of overloads}} #pragma acc routine(templ) seq // expected-error@+1{{OpenACC routine name 'NS::templ' names a set of overloads}} #pragma acc routine(NS::templ) seq // expected-error@+2{{use of undeclared identifier 'templ'; did you mean 'NS::templ'?}} -// expected-error@+1{{OpenACC routine name 'NS::templ' names a set of overloads}} +// expected-error@+1{{OpenACC routine name 'templ' names a set of overloads}} #pragma acc routine(templ) seq // expected-error@+1{{OpenACC routine name 'NS::templ' names a set of overloads}} #pragma acc routine(NS::templ) seq diff --git a/clang/test/ParserOpenACC/parse-wait-clause.c b/clang/test/ParserOpenACC/parse-wait-clause.c index 16e31a67c094f..5c006b4379a27 100644 --- a/clang/test/ParserOpenACC/parse-wait-clause.c +++ b/clang/test/ParserOpenACC/parse-wait-clause.c @@ -85,19 +85,16 @@ void func() { #pragma acc parallel wait (devnum: i + j:queues:) clause-list {} - // expected-error@+4{{use of undeclared identifier 'devnum'}} - // expected-error@+3{{expected ','}} + // expected-error@+3{{use of undeclared identifier 'devnum'}} // expected-error@+2{{expected ')'}} // expected-note@+1{{to match this '('}} #pragma acc parallel wait (queues:devnum: i + j {} - // expected-error@+2{{expected ','}} // expected-error@+1{{use of undeclared identifier 'devnum'}} #pragma acc parallel wait (queues:devnum: i + j) {} - // expected-error@+3{{expected ','}} // expected-error@+2{{use of undeclared identifier 'devnum'}} // expected-error@+1{{invalid OpenACC clause 'clause'}} #pragma acc parallel wait (queues:devnum: i + j) clause-list diff --git a/clang/test/ParserOpenACC/parse-wait-construct.c b/clang/test/ParserOpenACC/parse-wait-construct.c index 491c3bee4ac5a..27a3a02dc2637 100644 --- a/clang/test/ParserOpenACC/parse-wait-construct.c +++ b/clang/test/ParserOpenACC/parse-wait-construct.c @@ -68,18 +68,15 @@ void func() { // expected-error@+1{{invalid OpenACC clause 'clause'}} #pragma acc wait (devnum: i + j:queues:) clause-list - // expected-error@+4{{use of undeclared identifier 'devnum'}} - // expected-error@+3{{expected ','}} + // expected-error@+3{{use of undeclared identifier 'devnum'}} // expected-error@+2{{expected ')'}} // expected-note@+1{{to match this '('}} #pragma acc wait (queues:devnum: i + j - // expected-error@+2{{use of undeclared identifier 'devnum'}} - // expected-error@+1{{expected ','}} + // expected-error@+1{{use of undeclared identifier 'devnum'}} #pragma acc wait (queues:devnum: i + j) - // expected-error@+3{{use of undeclared identifier 'devnum'}} - // expected-error@+2{{expected ','}} + // expected-error@+2{{use of undeclared identifier 'devnum'}} // expected-error@+1{{invalid OpenACC clause 'clause'}} #pragma acc wait (queues:devnum: i + j) clause-list diff --git a/clang/test/Sema/PR28181.c b/clang/test/Sema/PR28181.c index 8d0a4ad33562a..7e9d5cc91038d 100644 --- a/clang/test/Sema/PR28181.c +++ b/clang/test/Sema/PR28181.c @@ -5,9 +5,9 @@ struct spinlock_t { } audit_skb_queue; void fn1(void) { - audit_skb_queue = (lock); // expected-error {{use of undeclared identifier 'lock'; did you mean 'long'?}} -} // expected-error@-1 {{assigning to 'struct spinlock_t' from incompatible type ''}} + audit_skb_queue = (lock); // expected-error {{use of undeclared identifier 'lock'}} +} void fn2(void) { - audit_skb_queue + (lock); // expected-error {{use of undeclared identifier 'lock'; did you mean 'long'?}} -} // expected-error@-1 {{reference to overloaded function could not be resolved; did you mean to call it?}} + audit_skb_queue + (lock); // expected-error {{use of undeclared identifier 'lock'}} +} diff --git a/clang/test/Sema/builtin-unary-fp.c b/clang/test/Sema/builtin-unary-fp.c index fb8e341156a59..9bfcb30b9eba3 100644 --- a/clang/test/Sema/builtin-unary-fp.c +++ b/clang/test/Sema/builtin-unary-fp.c @@ -17,5 +17,4 @@ void a(void) { check(__builtin_fpclassify(0,0,0,0,0, (invalid))); // expected-error{{use of undeclared identifier 'invalid'}} check(__builtin_fpclassify(0,0,0,0,0, (inf))); // expected-error{{use of undeclared identifier 'inf'}} - // expected-error@-1{{reference to overloaded function could not be resolved}} } diff --git a/clang/test/Sema/c23-delayed-typo-correction-crashes.c b/clang/test/Sema/c23-delayed-typo-correction-crashes.c new file mode 100644 index 0000000000000..6afd3fd32c366 --- /dev/null +++ b/clang/test/Sema/c23-delayed-typo-correction-crashes.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -std=c23 -fsyntax-only -verify %s + +void GH139913(...); +void GH139913_test() { + GH139913(CONCAT(foo, )); // expected-error {{use of undeclared identifier 'CONCAT'}} \ + expected-error {{use of undeclared identifier 'foo'}} \ + expected-error {{expected expression}} +} + +struct GH137867 { + char value; +}; +void GH137867_test() { + _Atomic(struct GH137867) t; + while (!atomic_load(&t.value)->value) // expected-error {{use of undeclared identifier 'atomic_load'}} \ + expected-error {{accessing a member of an atomic structure or union is undefined behavior}} + ; +} diff --git a/clang/test/Sema/delayed-typo-correction-crashes.c b/clang/test/Sema/delayed-typo-correction-crashes.c new file mode 100644 index 0000000000000..81c966789ccb5 --- /dev/null +++ b/clang/test/Sema/delayed-typo-correction-crashes.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -fblocks -ffixed-point -verify %s + +void GH137860_test(void) { + struct S { + char h; + }; + _Atomic struct S s = { .h = UINT8_MIN }; // expected-error {{use of undeclared identifier 'UINT8_MIN'}} + __c11_atomic_fetch_add(&s.h, UINT8_MIN); // expected-error {{use of undeclared identifier 'UINT8_MIN'}} \ + expected-error {{accessing a member of an atomic structure or union is undefined behavior}} +} + +int (^GH69470) (int i, int j) = ^(int i, int j) +{ return i / j; }/ j; // expected-error {{use of undeclared identifier 'j'}} + +void GH69874(void) { + *a = (a_struct){0}; // expected-error {{use of undeclared identifier 'a'}} \ + expected-error {{use of undeclared identifier 'a_struct'}} +} diff --git a/clang/test/Sema/invalid-member.cpp b/clang/test/Sema/invalid-member.cpp index 57ee187ccf4d5..0e3fec1b18eec 100644 --- a/clang/test/Sema/invalid-member.cpp +++ b/clang/test/Sema/invalid-member.cpp @@ -20,10 +20,12 @@ class Z { // Should be able to evaluate sizeof without crashing. static_assert(sizeof(Z) == 1, "No valid members"); -constexpr int N = undef; // expected-error {{use of undeclared identifier}} +constexpr int N = undef; // expected-error {{use of undeclared identifier}} \ + expected-note {{declared here}} template class ABC {}; class T { - ABC abc; + ABC abc; // expected-error {{non-type template argument is not a constant expression}} \ + expected-note {{initializer of 'N' is unknown}} }; static_assert(sizeof(T) == 1, "No valid members"); diff --git a/clang/test/Sema/typo-correction-ambiguity.cpp b/clang/test/Sema/typo-correction-ambiguity.cpp index 9dcff3d68c823..b2dae1d7696c3 100644 --- a/clang/test/Sema/typo-correction-ambiguity.cpp +++ b/clang/test/Sema/typo-correction-ambiguity.cpp @@ -18,12 +18,12 @@ void testAmbiguousNoSuggestions() namespace MultipleCorrectionsButNotAmbiguous { - int PrefixType_Name(int value); // expected-note {{'PrefixType_Name' declared here}} + int PrefixType_Name(int value); int PrefixType_MIN(); int PrefixType_MAX(); }; int testMultipleCorrectionsButNotAmbiguous() { - int val = MultipleCorrectionsButNotAmbiguous::PrefixType_Enum(0); // expected-error {{no member named 'PrefixType_Enum' in namespace 'MultipleCorrectionsButNotAmbiguous'; did you mean 'PrefixType_Name'?}} + int val = MultipleCorrectionsButNotAmbiguous::PrefixType_Enum(0); // expected-error {{no member named 'PrefixType_Enum' in namespace 'MultipleCorrectionsButNotAmbiguous'}} return val; } diff --git a/clang/test/Sema/typo-correction-no-hang.c b/clang/test/Sema/typo-correction-no-hang.c index e6041704ff324..da234a2c7373c 100644 --- a/clang/test/Sema/typo-correction-no-hang.c +++ b/clang/test/Sema/typo-correction-no-hang.c @@ -2,16 +2,15 @@ // PR50797 struct a { - int xxx; // expected-note {{'xxx' declared here}} + int xxx; }; int g_107; int g_108; int g_109; -struct a g_999; // expected-note 4{{'g_999' declared here}} +struct a g_999; -void b(void) { (g_910.xxx = g_910.xxx); } //expected-error 2{{use of undeclared identifier 'g_910'; did you mean 'g_999'}} +void b(void) { (g_910.xxx = g_910.xxx); } //expected-error 2{{use of undeclared identifier 'g_910'}} -void c(void) { (g_910.xxx = g_910.xxx1); } //expected-error 2{{use of undeclared identifier 'g_910'; did you mean 'g_999'}} \ - expected-error {{no member named 'xxx1' in 'struct a'; did you mean 'xxx'}} +void c(void) { (g_910.xxx = g_910.xxx1); } //expected-error 2{{use of undeclared identifier 'g_910'}} diff --git a/clang/test/Sema/typo-correction-no-hang.cpp b/clang/test/Sema/typo-correction-no-hang.cpp index 3c591645be25c..34b8486bed902 100644 --- a/clang/test/Sema/typo-correction-no-hang.cpp +++ b/clang/test/Sema/typo-correction-no-hang.cpp @@ -8,10 +8,12 @@ struct rdar38642201 { void rdar38642201_callee(int x, int y); void rdar38642201_caller() { - struct rdar38642201 structVar; + struct rdar38642201 structVar; //expected-note 2{{'structVar' declared here}} rdar38642201_callee( - structVar1.fieldName1.member1, //expected-error{{use of undeclared identifier 'structVar1'}} - structVar2.fieldName2.member2); //expected-error{{use of undeclared identifier 'structVar2'}} + structVar1.fieldName1.member1, //expected-error{{use of undeclared identifier 'structVar1'}} \ + expected-error{{no member named 'fieldName1' in 'rdar38642201'}} + structVar2.fieldName2.member2); //expected-error{{use of undeclared identifier 'structVar2'}} \ + expected-error{{no member named 'fieldName2' in 'rdar38642201'}} } // Similar reproducer. @@ -20,7 +22,7 @@ class A { int minut() const = delete; int hour() const = delete; - int longit() const; //expected-note{{'longit' declared here}} + int longit() const; int latit() const; }; @@ -35,6 +37,6 @@ int Foo(const B &b) { } int Bar(const B &b) { - return b.depar().longitude() + //expected-error{{no member named 'longitude' in 'A'; did you mean 'longit'?}} + return b.depar().longitude() + //expected-error{{no member named 'longitude' in 'A'}} b.depar().latitude(); //expected-error{{no member named 'latitude' in 'A'}} } diff --git a/clang/test/Sema/typo-correction-recursive.cpp b/clang/test/Sema/typo-correction-recursive.cpp index b39beb5493f65..a7d7127564b75 100644 --- a/clang/test/Sema/typo-correction-recursive.cpp +++ b/clang/test/Sema/typo-correction-recursive.cpp @@ -8,13 +8,13 @@ class DeepClass { public: - void trigger() const; // expected-note {{'trigger' declared here}} + void trigger() const; }; class Y { public: - const DeepClass& getX() const { return m_deepInstance; } // expected-note {{'getX' declared here}} + const DeepClass& getX() const { return m_deepInstance; } private: DeepClass m_deepInstance; int m_n; @@ -23,7 +23,7 @@ class Y class Z { public: - const Y& getY0() const { return m_y0; } // expected-note {{'getY0' declared here}} + const Y& getY0() const { return m_y0; } const Y& getActiveY() const { return m_y0; } private: @@ -35,9 +35,9 @@ Z z_obj; void testMultipleCorrections() { - z_obj.getY2(). // expected-error {{no member named 'getY2' in 'Z'; did you mean 'getY0'}} - getM(). // expected-error {{no member named 'getM' in 'Y'; did you mean 'getX'}} - triggee(); // expected-error {{no member named 'triggee' in 'DeepClass'; did you mean 'trigger'}} + z_obj.getY2(). // expected-error {{no member named 'getY2' in 'Z'}} + getM(). + triggee(); } void testNoCorrections() @@ -53,19 +53,19 @@ struct A { C get_me_a_C(); }; struct B { - D get_me_a_D(); // expected-note {{'get_me_a_D' declared here}} + D get_me_a_D(); }; class Scope { public: A make_an_A(); - B make_a_B(); // expected-note {{'make_a_B' declared here}} + B make_a_B(); }; Scope scope_obj; int testDiscardedCorrections() { - return scope_obj.make_an_E(). // expected-error {{no member named 'make_an_E' in 'Scope'; did you mean 'make_a_B'}} - get_me_a_Z().value; // expected-error {{no member named 'get_me_a_Z' in 'B'; did you mean 'get_me_a_D'}} + return scope_obj.make_an_E(). // expected-error {{no member named 'make_an_E' in 'Scope'}} + get_me_a_Z().value; } class AmbiguousHelper { @@ -120,13 +120,13 @@ int testDeepAmbiguity() { } struct Dog { - int age; //expected-note{{'age' declared here}} - int size; //expected-note{{'size' declared here}} + int age; + int size; }; int from_dog_years(int DogYears, int DogSize); int get_dog_years() { struct Dog doggo; - return from_dog_years(doggo.agee, //expected-error{{no member named 'agee' in 'Dog'; did you mean 'age'}} - doggo.sizee); //expected-error{{no member named 'sizee' in 'Dog'; did you mean 'size'}} + return from_dog_years(doggo.agee, //expected-error{{no member named 'agee' in 'Dog'}} + doggo.sizee); //expected-error{{no member named 'sizee' in 'Dog'}} } diff --git a/clang/test/Sema/typo-correction.c b/clang/test/Sema/typo-correction.c index 4157207a9ac42..510a67e725f9c 100644 --- a/clang/test/Sema/typo-correction.c +++ b/clang/test/Sema/typo-correction.c @@ -50,10 +50,12 @@ void fn1(void) { cabs(errij); // expected-error {{use of undeclared identifier 'errij'}} } -extern long afunction(int); +extern long afunction(int); // expected-note {{'afunction' declared here}} \ + expected-note {{passing argument to parameter here}} void fn2(void) { f(THIS_IS_AN_ERROR, // expected-error {{use of undeclared identifier 'THIS_IS_AN_ERROR'}} - afunction(afunction_)); // expected-error {{use of undeclared identifier 'afunction_'}} + afunction(afunction_)); // expected-error {{use of undeclared identifier 'afunction_'}} \ + expected-error {{incompatible pointer to integer conversion passing 'long (int)' to parameter of type 'int'}} } int d = X ? d : L; // expected-error 2 {{use of undeclared identifier}} @@ -94,22 +96,24 @@ struct rdar38642201 { void rdar38642201_callee(int x, int y); void rdar38642201_caller(void) { - struct rdar38642201 structVar; + struct rdar38642201 structVar; // expected-note 2{{'structVar' declared here}} rdar38642201_callee( - structVar1.fieldName1.member1, //expected-error{{use of undeclared identifier 'structVar1'}} - structVar2.fieldName2.member2); //expected-error{{use of undeclared identifier 'structVar2'}} + structVar1.fieldName1.member1, //expected-error{{use of undeclared identifier 'structVar1'}} \ + expected-error{{no member named 'fieldName1' in 'struct rdar38642201'}} + structVar2.fieldName2.member2); //expected-error{{use of undeclared identifier 'structVar2'}} \ + expected-error{{no member named 'fieldName2' in 'struct rdar38642201'}} } void PR40286_g(int x, int y); void PR40286_h(int x, int y, int z); -void PR40286_1(int the_value) { - PR40286_g(the_walue); // expected-error {{use of undeclared identifier 'the_walue'}} +void PR40286_1(int the_value) { // expected-note {{'the_value' declared here}} + PR40286_g(the_walue, 0); // expected-error {{use of undeclared identifier 'the_walue'}} } -void PR40286_2(int the_value) { - PR40286_h(the_value, the_walue); // expected-error {{use of undeclared identifier 'the_walue'}} +void PR40286_2(int the_value) { // expected-note {{'the_value' declared here}} + PR40286_h(the_value, the_walue, 0); // expected-error {{use of undeclared identifier 'the_walue'}} } -void PR40286_3(int the_value) { - PR40286_h(the_walue); // expected-error {{use of undeclared identifier 'the_walue'}} +void PR40286_3(int the_value) { // expected-note {{'the_value' declared here}} + PR40286_h(the_walue, 0, 0); // expected-error {{use of undeclared identifier 'the_walue'}} } void PR40286_4(int the_value) { // expected-note {{'the_value' declared here}} PR40286_h(the_value, the_value, the_walue); // expected-error {{use of undeclared identifier 'the_walue'; did you mean 'the_value'?}} diff --git a/clang/test/SemaCXX/arrow-operator.cpp b/clang/test/SemaCXX/arrow-operator.cpp index 295dea3c1756c..a789c4e36e4c9 100644 --- a/clang/test/SemaCXX/arrow-operator.cpp +++ b/clang/test/SemaCXX/arrow-operator.cpp @@ -47,23 +47,22 @@ class wrapped_ptr { public: wrapped_ptr(T* ptr) : ptr_(ptr) {} T* operator->() { return ptr_; } - void Check(); // expected-note {{'Check' declared here}} + void Check(); private: T *ptr_; }; class Worker { public: - void DoSomething(); // expected-note {{'DoSomething' declared here}} + void DoSomething(); void Chuck(); }; void test() { wrapped_ptr worker(new Worker); worker.DoSomething(); // expected-error {{no member named 'DoSomething' in 'arrow_suggest::wrapped_ptr'; did you mean to use '->' instead of '.'?}} - worker.DoSamething(); // expected-error {{no member named 'DoSamething' in 'arrow_suggest::wrapped_ptr'; did you mean to use '->' instead of '.'?}} \ - // expected-error {{no member named 'DoSamething' in 'arrow_suggest::Worker'; did you mean 'DoSomething'?}} - worker.Chuck(); // expected-error {{no member named 'Chuck' in 'arrow_suggest::wrapped_ptr'; did you mean 'Check'?}} + worker.DoSamething(); // expected-error {{no member named 'DoSamething' in 'arrow_suggest::wrapped_ptr'}} + worker.Chuck(); // expected-error {{no member named 'Chuck' in 'arrow_suggest::wrapped_ptr'}} } } // namespace arrow_suggest diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index eeeb58f1a771a..ab4e50072f654 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -1888,10 +1888,11 @@ namespace PR15884 { } namespace AfterError { - constexpr int error() { + constexpr int error() { // pre-cxx23-error {{no return statement in constexpr function}} return foobar; // expected-error {{undeclared identifier}} - } - constexpr int k = error(); // expected-error {{constexpr variable 'k' must be initialized by a constant expression}} + } // cxx23-note {{control reached end of constexpr function}} + constexpr int k = error(); // cxx23-error {{constexpr variable 'k' must be initialized by a constant expression}} \ + cxx23-note {{in call to 'error()'}} } namespace std { diff --git a/clang/test/SemaCXX/conversion-function.cpp b/clang/test/SemaCXX/conversion-function.cpp index b653a3bf1a1d2..717c73c4786eb 100644 --- a/clang/test/SemaCXX/conversion-function.cpp +++ b/clang/test/SemaCXX/conversion-function.cpp @@ -458,7 +458,7 @@ namespace PR18234 { #endif } a; A::S s = a; // expected-error {{no viable conversion from 'struct A' to 'A::S'}} - A::E e = a; + A::E e = a; // expected-note {{'e' declared here}} bool k1 = e == A::e; // expected-error {{no member named 'e'}} bool k2 = e.n == 0; } diff --git a/clang/test/SemaCXX/coroutines.cpp b/clang/test/SemaCXX/coroutines.cpp index 068fdab4bfe38..c9cefeb30c15a 100644 --- a/clang/test/SemaCXX/coroutines.cpp +++ b/clang/test/SemaCXX/coroutines.cpp @@ -8,19 +8,16 @@ // RUN: not %clang_cc1 -std=c++20 -fsyntax-only %s -fcxx-exceptions -fexceptions -Wunused-result 2>&1 | FileCheck %s void no_coroutine_traits_bad_arg_await() { - co_await a; // expected-error {{include }} - // expected-error@-1 {{use of undeclared identifier 'a'}} + co_await a; // expected-error {{use of undeclared identifier 'a'}} } void no_coroutine_traits_bad_arg_yield() { - co_yield a; // expected-error {{include }} - // expected-error@-1 {{use of undeclared identifier 'a'}} + co_yield a; // expected-error {{use of undeclared identifier 'a'}} } void no_coroutine_traits_bad_arg_return() { - co_return a; // expected-error {{include }} - // expected-error@-1 {{use of undeclared identifier 'a'}} + co_return a; // expected-error {{use of undeclared identifier 'a'}} } void no_coroutine_traits() { @@ -208,8 +205,7 @@ void mixed_yield() { void mixed_yield_invalid() { co_yield blah; // expected-error {{use of undeclared identifier}} - // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}} - return; // expected-error {{return statement not allowed in coroutine}} + return; } void mixed_yield_return_first(bool b) { @@ -231,8 +227,7 @@ void mixed_return_for_range(bool b, T t) { template void mixed_yield_template(T) { co_yield blah; // expected-error {{use of undeclared identifier}} - // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}} - return; // expected-error {{return statement not allowed in coroutine}} + return; } template @@ -314,10 +309,9 @@ template void mixed_coreturn_template(void_tag, bool, int); // expected-note {{r template void mixed_coreturn_template2(bool b, T) { if (b) - co_return v; // expected-note {{use of 'co_return'}} - // expected-error@-1 {{use of undeclared identifier 'v'}} + co_return v; // expected-error {{use of undeclared identifier 'v'}} else - return; // expected-error {{not allowed in coroutine}} + return; } struct promise_handle; diff --git a/clang/test/SemaCXX/cxx-delayed-typo-correction-crashes.cpp b/clang/test/SemaCXX/cxx-delayed-typo-correction-crashes.cpp new file mode 100644 index 0000000000000..f3aa051532815 --- /dev/null +++ b/clang/test/SemaCXX/cxx-delayed-typo-correction-crashes.cpp @@ -0,0 +1,67 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace GH138850 { +void test() { + int tmp = add(int, 0, 0); // expected-error {{expected '(' for function-style cast or type construction}} \ + expected-note {{previous definition is here}} + uint tmp = add(uint, 1, 1); // expected-error {{use of undeclared identifier 'uint'; did you mean 'int'?}} \ + expected-error {{redefinition of 'tmp'}} \ + expected-error {{use of undeclared identifier 'uint'}} + call(void, f, (int)tmp); // expected-error {{expected '(' for function-style cast or type construction}} \ + expected-error {{use of undeclared identifier 'f'}} +} +} + +namespace GH107840 { +struct tm {}; // expected-note {{'tm' declared here}} + +auto getCache = [&] { // expected-error {{non-local lambda expression cannot have a capture-default}} + ::foo([=] { // expected-error {{no member named 'foo' in the global namespace}} + tms time; // expected-error {{unknown type name 'tms'; did you mean 'tm'?}} + (void)time; + }); +}; +} + +namespace GH59391 { +template class c { + c(b); + b e; + void f() { + for (auto core : a::c(cores)) { // expected-error {{use of undeclared identifier 'cores'}} \ + expected-error {{use of undeclared identifier 'a'}} + } + } +}; +} + +namespace GH45915 { +short g_volatile_ushort; // expected-note {{'g_volatile_ushort' declared here}} +namespace a { + int b = l_volatile_uwchar.a ::c ::~d<>; // expected-error {{use of undeclared identifier 'l_volatile_uwchar'}} \ + expected-error {{no member named 'd' in namespace 'GH45915::a'}} +} +} + +namespace GH45891 { +int a = b.c < enum , > :: template ~d < > [ e; // expected-error {{use of undeclared identifier 'b'}} \ + expected-error {{expected identifier or '{'}} \ + expected-error {{expected ';' after top level declarator}} +} + +namespace GH32903 { +void +B( + char cat_dog_3, char cat_dog_2, char cat_dog_1, char cat_dog_0, char pigeon_dog_3, char pigeon_dog_2, + char pigeon_dog_1, char pigeon_dog_0, short &elefant15_lion, short &elefant14_lion, short &elefant13_lion, // expected-note 3 {{declared here}} + short &elefant12_lion, short &elefant11_lion, short &elefant10_lion, short &elefant9_lion, short &elefant8_lion, // expected-note 5 {{declared here}} + short &elefant7_lion, short &elefant6_lion, short &elefant5_lion, short &elefant4_lion, short &elefant3_lion, // expected-note 2 {{declared here}} + short &elefant2_lion, short &elefant1_lion, short &elefant0_lion, char& no_animal) +{ + + A( // FIXME: it's surprising that we don't issue a "use of undeclared identifier" diagnostic for the call itself. + elefant_15_lion, elefant_14_lion, elefant_13_lion, elefant_12_lion, elefant_11_lion, elefant_10_lion, elefant_9_lion, // expected-error 7 {{use of undeclared identifier}} + elefant_8_lion, elefant_7_lion, elefant_6_lion, elefant_5_lion, elefant_4_lion, elefant_3_lion, elefant_2_lion, // expected-error 7 {{use of undeclared identifier}} + elefant_1_lion, elefant_0_lion, no_animal, other_mammal); // expected-error 3 {{use of undeclared identifier}} +} +} diff --git a/clang/test/SemaCXX/cxx1z-decomposition.cpp b/clang/test/SemaCXX/cxx1z-decomposition.cpp index 95c64bc3b8bff..6ee1249a66c3f 100644 --- a/clang/test/SemaCXX/cxx1z-decomposition.cpp +++ b/clang/test/SemaCXX/cxx1z-decomposition.cpp @@ -121,7 +121,8 @@ void for_range() { } int error_recovery() { - auto [foobar]; // expected-error {{requires an initializer}} + auto [foobar]; // expected-error {{requires an initializer}} \ + expected-note {{'foobar' declared here}} return foobar_; // expected-error {{undeclared identifier 'foobar_'}} } diff --git a/clang/test/SemaCXX/cxx20-delayed-typo-correction-crashes.cpp b/clang/test/SemaCXX/cxx20-delayed-typo-correction-crashes.cpp new file mode 100644 index 0000000000000..a16a7f8255f7c --- /dev/null +++ b/clang/test/SemaCXX/cxx20-delayed-typo-correction-crashes.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s + +#include "Inputs/std-coroutine.h" + +namespace GH58172 { +template +int f2(int, Fn&&) +{ + return 0; +} + +int f1() +{ + return f2(v1, []() -> task { // expected-error {{no template named 'task'}} \ + expected-error {{use of undeclared identifier 'v1'}} + co_return v2; // expected-error {{use of undeclared identifier 'v2'}} + }); +} +} diff --git a/clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp b/clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp index 5c0d89d9125f2..1bc7f2cce3c92 100644 --- a/clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp +++ b/clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp @@ -61,7 +61,7 @@ struct A : X { // expected-error {{no template named 'X'}} // Similarly for treating overload sets of functions as template names. struct g {}; // expected-error {{'g' refers to a function template}} g::Y xy; // expected-error {{no template named 'g'}} FIXME lies -void xf(g x); // expected-error {{variable has incomplete type 'void'}} expected-error 1+{{}} expected-note {{}} +void xf(g x); // expected-error {{variable has incomplete type 'void'}} expected-error 1+{{}} struct B : g { // expected-error {{expected class name}} B() : g() {} // expected-error {{expected class member or base class name}} }; diff --git a/clang/test/SemaCXX/destructor.cpp b/clang/test/SemaCXX/destructor.cpp index ed4802943ad3f..b9e0b17d510ab 100644 --- a/clang/test/SemaCXX/destructor.cpp +++ b/clang/test/SemaCXX/destructor.cpp @@ -553,14 +553,11 @@ namespace crash_on_invalid_base_dtor { struct Test { virtual ~Test(); }; -struct Baz : public Test { // expected-warning {{non-virtual destructor}} +struct Baz : public Test { Baz() {} - ~Baz() = defaul; // expected-error {{undeclared identifier 'defaul'}} \ - // expected-error {{initializer on function}} \ - // expected-note {{overridden virtual function is here}} + ~Baz() = defaul; // expected-error {{undeclared identifier 'defaul'}} }; -struct Foo : public Baz { // expected-error {{cannot override a non-deleted function}} \ - // expected-note {{destructor of 'Foo' is implicitly deleted}} +struct Foo : public Baz { Foo() {} }; } @@ -579,11 +576,9 @@ static_assert(!__is_trivially_constructible(Foo, Foo &&), ""); namespace GH97230 { struct X { - ~X() = defaul; // expected-error {{initializer on function does not look like a pure-specifier}} \ - // expected-error {{use of undeclared identifier 'defaul'}} + ~X() = defaul; // expected-error {{use of undeclared identifier 'defaul'}} }; -struct Y : X {} y1{ }; // expected-error {{call to implicitly-deleted default constructor of 'struct Y'}} \ - // expected-note {{default constructor of 'Y' is implicitly deleted because base class 'X' has no destructor}} +struct Y : X {} y1{ }; } namespace GH121706 { diff --git a/clang/test/SemaCXX/invalid-if-constexpr.cpp b/clang/test/SemaCXX/invalid-if-constexpr.cpp index 0007f2739cbbd..9f27741871484 100644 --- a/clang/test/SemaCXX/invalid-if-constexpr.cpp +++ b/clang/test/SemaCXX/invalid-if-constexpr.cpp @@ -2,12 +2,16 @@ namespace GH61885 { void similar() { // expected-note {{'similar' declared here}} - if constexpr (similer<>) {} // expected-error {{use of undeclared identifier 'similer'; did you mean 'similar'?}} + if constexpr (similer<>) {} // expected-error {{use of undeclared identifier 'similer'; did you mean 'similar'?}} \ + expected-warning {{address of function 'similar<>' will always evaluate to 'true'}} \ + expected-note {{prefix with the address-of operator to silence this warning}} } -void a() { if constexpr (__adl_swap<>) {}} // expected-error{{use of undeclared identifier '__adl_swap'; did you mean '__sync_swap'?}} +void a() { if constexpr (__adl_swap<>) {}} // expected-error{{use of undeclared identifier '__adl_swap'}} int AA() { return true;} // expected-note {{'AA' declared here}} -void b() { if constexpr (AAA<>) {}} // expected-error {{use of undeclared identifier 'AAA'; did you mean 'AA'?}} +void b() { if constexpr (AAA<>) {}} // expected-error {{use of undeclared identifier 'AAA'; did you mean 'AA'?}} \ + expected-warning {{address of function 'AA<>' will always evaluate to 'true'}} \ + expected-note {{prefix with the address-of operator to silence this warning}} } diff --git a/clang/test/SemaCXX/member-expr.cpp b/clang/test/SemaCXX/member-expr.cpp index 0596e40f6c2f6..902b09097a120 100644 --- a/clang/test/SemaCXX/member-expr.cpp +++ b/clang/test/SemaCXX/member-expr.cpp @@ -96,11 +96,11 @@ namespace test5 { namespace PR7508 { struct A { struct CleanupScope {}; - void PopCleanupBlock(); // expected-note{{'PopCleanupBlock' declared here}} + void PopCleanupBlock(); }; void foo(A &a) { - a.PopCleanupScope(); // expected-error{{no member named 'PopCleanupScope' in 'PR7508::A'; did you mean 'PopCleanupBlock'?}} + a.PopCleanupScope(); // expected-error{{no member named 'PopCleanupScope' in 'PR7508::A'}} } } @@ -189,7 +189,7 @@ namespace PR15045 { } struct bar { - void func(); // expected-note {{'func' declared here}} + void func(); }; struct foo { @@ -207,7 +207,7 @@ namespace PR15045 { // Show that recovery has happened by also triggering typo correction e->Func(); // expected-error {{member reference type 'bar' is not a pointer; did you mean to use '.'?}} \ - // expected-error {{no member named 'Func' in 'PR15045::bar'; did you mean 'func'?}} + // expected-error {{no member named 'Func' in 'PR15045::bar'}} // Make sure a fixit isn't given in the case that the '->' isn't actually // the problem (the problem is with the return value of an operator->). diff --git a/clang/test/SemaCXX/nested-name-spec.cpp b/clang/test/SemaCXX/nested-name-spec.cpp index 36398aed7ac5f..abeaba9d8dde2 100644 --- a/clang/test/SemaCXX/nested-name-spec.cpp +++ b/clang/test/SemaCXX/nested-name-spec.cpp @@ -409,7 +409,8 @@ T1 var_1a; T1 var_1b; // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}} template int F() {} int (*X1)() = (B1::B2 ? F<1> : F<2>); -int (*X2)() = (B1:B2 ? F<1> : F<2>); // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}} +int (*X2)() = (B1:B2 ? F<1> : F<2>); // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}} \ + expected-note{{'PR18587::X2' declared here}} // Bit fields + templates struct S7a { @@ -445,7 +446,8 @@ namespace PR16951 { int x4 = enumerator_2::ENUMERATOR_2; // expected-warning{{use of enumeration in a nested name specifier is a C++11 extension}} int x5 = enumerator_2::X2; // expected-warning{{use of enumeration in a nested name specifier is a C++11 extension}} \ - // expected-error{{no member named 'X2' in 'PR16951::enumerator_2'}} + // expected-error{{no member named 'X2' in 'PR16951::enumerator_2'}} \ + // expected-error{{cannot initialize a variable of type 'int' with an lvalue of type 'int (*)()'}} } diff --git a/clang/test/SemaCXX/pr13394-crash-on-invalid.cpp b/clang/test/SemaCXX/pr13394-crash-on-invalid.cpp deleted file mode 100644 index 304ee92f6a8da..0000000000000 --- a/clang/test/SemaCXX/pr13394-crash-on-invalid.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -// Don't crash (PR13394). - -namespace stretch_v1 { - struct closure_t { - const stretch_v1::ops_t* d_methods; // expected-error {{no type named 'ops_t' in namespace 'stretch_v1'}} - }; -} -namespace gatekeeper_v1 { - namespace gatekeeper_factory_v1 { - struct closure_t { // expected-note {{'closure_t' declared here}} expected-note {{'gatekeeper_factory_v1::closure_t' declared here}} - gatekeeper_v1::closure_t* create(); // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1'; did you mean simply 'closure_t'?}} - }; - } - // FIXME: Typo correction should remove the 'gatekeeper_v1::' name specifier - gatekeeper_v1::closure_t *x; // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1'; did you mean 'gatekeeper_factory_v1::closure_t'}} -} - -namespace Foo { -struct Base { - void Bar() {} // expected-note{{'Bar' declared here}} -}; -} - -struct Derived : public Foo::Base { - void test() { - Foo::Bar(); // expected-error{{no member named 'Bar' in namespace 'Foo'; did you mean simply 'Bar'?}} - } -}; diff --git a/clang/test/SemaCXX/return.cpp b/clang/test/SemaCXX/return.cpp index 17d7892d8dbd9..796c9ae91dedc 100644 --- a/clang/test/SemaCXX/return.cpp +++ b/clang/test/SemaCXX/return.cpp @@ -130,5 +130,5 @@ void cxx_unresolved_expr() { // CXXUnresolvedConstructExpr, and the missing ')' gives it an invalid source // location for its rparen. Check that emitting a diag on the range of the // expr doesn't assert. - return int(undeclared, 4; // expected-error {{expected ')'}} expected-note{{to match this '('}} expected-error {{use of undeclared identifier 'undeclared'}} + return int(undeclared, 4; // expected-error {{use of undeclared identifier 'undeclared'}} } diff --git a/clang/test/SemaCXX/typo-correction-crash.cpp b/clang/test/SemaCXX/typo-correction-crash.cpp index 2a77c9df505e8..434b70e3c5097 100644 --- a/clang/test/SemaCXX/typo-correction-crash.cpp +++ b/clang/test/SemaCXX/typo-correction-crash.cpp @@ -4,10 +4,10 @@ auto check1() { return s; // expected-error {{use of undeclared identifier 's'}} } -int test = 11; // expected-note 2 {{'test' declared here}} +int test = 11; // expected-note 3 {{'test' declared here}} auto check2() { return "s"; - return tes; // expected-error {{use of undeclared identifier 'tes'; did you mean 'test'?}} + return tes; // expected-error {{use of undeclared identifier 'tes'}} // expected-error@-1 {{deduced as 'int' here but deduced as 'const char *' in earlier}} } @@ -16,9 +16,8 @@ template struct is_same { static constexpr bool value = true; }; auto L1 = [] { return s; }; // expected-error {{use of undeclared identifier 's'}} using T1 = decltype(L1()); -// FIXME: Suppress the 'undeclared identifier T1' diagnostic, the UsingDecl T1 is discarded because of an invalid L1(). -static_assert(is_same::value, "Return statement should be discarded"); // expected-error {{use of undeclared identifier 'T1'}} -auto L2 = [] { return tes; }; // expected-error {{use of undeclared identifier 'tes'; did you mean 'test'?}} +static_assert(is_same::value, "Return statement should be discarded"); +auto L2 = [] { return tes; }; // expected-error {{use of undeclared identifier 'tes'}} using T2 = decltype(L2()); static_assert(is_same::value, "Return statement was corrected"); @@ -32,13 +31,13 @@ FooRecord::NestedNamespace::type x; // expected-error {{no member named 'NestedN void cast_expr(int g) { +int(n)(g); } // expected-error {{undeclared identifier 'n'}} -void bind() { for (const auto& [test,_] : _test_) { }; } // expected-error {{undeclared identifier '_test_'}} +void bind() { for (const auto& [test,_] : _test_) { }; } // expected-error {{undeclared identifier '_test_'}} \ + expected-error {{invalid range expression of type 'int'; no viable 'begin' function available}} namespace NoCrash { class S { void Function(int a) { - unknown1(unknown2, Function, unknown3); // expected-error 2{{use of undeclared identifier}} \ - expected-error {{reference to non-static member function must be called}} + unknown1(unknown2, Function, unknown3); // expected-error 2{{use of undeclared identifier}} } }; } @@ -46,8 +45,6 @@ class S { namespace NoCrashOnCheckArgAlignment { template void b(a &); void test() { - for (auto file_data :b(files_db_data)); // expected-error {{use of undeclared identifier 'files_db_data'; did you mean 'file_data'?}} \ - // expected-note {{'file_data' declared here}} \ - // expected-error {{cannot use type 'void' as a range}} + for (auto file_data :b(files_db_data)); // expected-error {{use of undeclared identifier 'files_db_data'}} } } diff --git a/clang/test/SemaCXX/typo-correction-cxx11.cpp b/clang/test/SemaCXX/typo-correction-cxx11.cpp index 8c588203cc128..9eb5f9c299629 100644 --- a/clang/test/SemaCXX/typo-correction-cxx11.cpp +++ b/clang/test/SemaCXX/typo-correction-cxx11.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s namespace PR23186 { -decltype(ned); // expected-error-re {{use of undeclared identifier 'ned'{{$}}}} +decltype(ned); // expected-error {{use of undeclared identifier 'ned'}} // The code below was triggering an UNREACHABLE in ASTContext::getTypeInfoImpl // once the above code failed to recover properly after making the bogus // correction of 'ned' to 'new'. @@ -19,8 +19,9 @@ struct S { namespace PR23140 { auto lneed = gned.*[] {}; // expected-error-re {{use of undeclared identifier 'gned'{{$}}}} -void test(int aaa, int bbb, int thisvar) { // expected-note {{'thisvar' declared here}} - int thatval = aaa * (bbb + thatvar); // expected-error {{use of undeclared identifier 'thatvar'; did you mean 'thisvar'?}} +void test(int aaa, int bbb, int thisvar) { + int thatval = aaa * (bbb + thatvar); // expected-error {{use of undeclared identifier 'thatvar'; did you mean 'thatval'}} \ + expected-note {{'thatval' declared here}} } } @@ -54,7 +55,7 @@ void run(A *annotations) { auto &annotation = *annotations; auto new_it = new_annotations.find(5); - auto &new_anotation = new_it.second; // expected-note {{'new_anotation' declared here}} - new_annotation->Swap(&annotation); // expected-error {{use of undeclared identifier 'new_annotation'; did you mean 'new_anotation'?}} + auto &new_anotation = new_it.second; + new_annotation->Swap(&annotation); // expected-error {{use of undeclared identifier 'new_annotation'}} } } diff --git a/clang/test/SemaCXX/typo-correction-delayed.cpp b/clang/test/SemaCXX/typo-correction-delayed.cpp deleted file mode 100644 index fdb1f740fda6a..0000000000000 --- a/clang/test/SemaCXX/typo-correction-delayed.cpp +++ /dev/null @@ -1,216 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++11-extensions %s -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -Wno-c++11-extensions %s -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s - -struct A {}; -struct B {}; -struct D { - A fizbin; // expected-note 2 {{declared here}} - A foobar; // expected-note 2 {{declared here}} - B roxbin; // expected-note 2 {{declared here}} - B toobad; // expected-note 2 {{declared here}} - void BooHoo(); - void FoxBox(); -}; - -void something(A, B); -void test() { - D obj; - something(obj.fixbin, // expected-error {{did you mean 'fizbin'?}} - obj.toobat); // expected-error {{did you mean 'toobad'?}} - something(obj.toobat, // expected-error {{did you mean 'foobar'?}} - obj.fixbin); // expected-error {{did you mean 'roxbin'?}} - something(obj.fixbin, // expected-error {{did you mean 'fizbin'?}} - obj.fixbin); // expected-error {{did you mean 'roxbin'?}} - something(obj.toobat, // expected-error {{did you mean 'foobar'?}} - obj.toobat); // expected-error {{did you mean 'toobad'?}} - // Both members could be corrected to methods, but that isn't valid. - something(obj.boohoo, // expected-error-re {{no member named 'boohoo' in 'D'{{$}}}} - obj.foxbox); // expected-error-re {{no member named 'foxbox' in 'D'{{$}}}} - // The first argument has a usable correction but the second doesn't. - something(obj.boobar, // expected-error-re {{no member named 'boobar' in 'D'{{$}}}} - obj.foxbox); // expected-error-re {{no member named 'foxbox' in 'D'{{$}}}} -} - -// Ensure the delayed typo correction does the right thing when trying to -// recover using a seemingly-valid correction for which a valid expression to -// replace the TypoExpr cannot be created (but which does have a second -// correction candidate that would be a valid and usable correction). -class Foo { -public: - template <> void testIt(); // expected-error {{no function template matches}} - void textIt(); // expected-note {{'textIt' declared here}} -}; -void testMemberExpr(Foo *f) { - f->TestIt(); // expected-error {{no member named 'TestIt' in 'Foo'; did you mean 'textIt'?}} -} - -void callee(double, double); -void testNoCandidates() { - callee(xxxxxx, // expected-error-re {{use of undeclared identifier 'xxxxxx'{{$}}}} - zzzzzz); // expected-error-re {{use of undeclared identifier 'zzzzzz'{{$}}}} -} - -class string {}; -struct Item { - void Nest(); - string text(); - Item* next(); // expected-note {{'next' declared here}} -}; -void testExprFilter(Item *i) { - Item *j; - j = i->Next(); // expected-error {{no member named 'Next' in 'Item'; did you mean 'next'?}} -} - -// Test that initializer expressions are handled correctly and that the type -// being initialized is taken into account when choosing a correction. -namespace initializerCorrections { -struct Node { - string text() const; - // Node* Next() is not implemented yet -}; -void f(Node *node) { - // text is only an edit distance of 1 from Next, but would trigger type - // conversion errors if used in this initialization expression. - Node *next = node->Next(); // expected-error-re {{no member named 'Next' in 'initializerCorrections::Node'{{$}}}} -} - -struct LinkedNode { - LinkedNode* next(); // expected-note {{'next' declared here}} - string text() const; -}; -void f(LinkedNode *node) { - // text and next are equidistant from Next, but only one results in a valid - // initialization expression. - LinkedNode *next = node->Next(); // expected-error {{no member named 'Next' in 'initializerCorrections::LinkedNode'; did you mean 'next'?}} -} - -struct NestedNode { - NestedNode* Nest(); - NestedNode* next(); - string text() const; -}; -void f(NestedNode *node) { - // There are two equidistant, usable corrections for Next: next and Nest - NestedNode *next = node->Next(); // expected-error-re {{no member named 'Next' in 'initializerCorrections::NestedNode'{{$}}}} -} -} - -namespace PR21669 { -void f(int *i) { - // Check that arguments to a builtin with custom type checking are corrected - // properly, since calls to such builtins bypass much of the normal code path - // for building and checking the call. - __atomic_load(i, i, something_something); // expected-error-re {{use of undeclared identifier 'something_something'{{$}}}} -} -} - -const int DefaultArg = 9; // expected-note {{'DefaultArg' declared here}} -template struct S {}; // expected-error {{use of undeclared identifier 'defaultArg'; did you mean 'DefaultArg'?}} -S<1> s; - -namespace foo {} -void test_paren_suffix() { - foo::bar({5, 6}); // expected-error-re {{no member named 'bar' in namespace 'foo'{{$}}}} -#if __cplusplus <= 199711L - // expected-error@-2 {{expected expression}} -#endif -} - -const int kNum = 10; // expected-note {{'kNum' declared here}} -class SomeClass { - int Kind; -public: - explicit SomeClass() : Kind(kSum) {} // expected-error {{use of undeclared identifier 'kSum'; did you mean 'kNum'?}} -}; - -// There used to be an issue with typo resolution inside overloads. -struct AssertionResult { ~AssertionResult(); }; -AssertionResult Overload(const char *a); -AssertionResult Overload(int a); -void UseOverload() { - // expected-note@+1 {{'result' declared here}} - const char *result; - // expected-error@+1 {{use of undeclared identifier 'resulta'; did you mean 'result'?}} - Overload(resulta); -} - -namespace PR21925 { -struct X { - int get() { return 7; } // expected-note {{'get' declared here}} -}; -void test() { - X variable; // expected-note {{'variable' declared here}} - - // expected-error@+2 {{use of undeclared identifier 'variableX'; did you mean 'variable'?}} - // expected-error@+1 {{no member named 'getX' in 'PR21925::X'; did you mean 'get'?}} - int x = variableX.getX(); -} -} - -namespace PR21905 { -int (*a)() = (void)Z; // expected-error-re {{use of undeclared identifier 'Z'{{$}}}} \ - // expected-error {{cannot initialize a variable of type 'int (*)()' with an rvalue of type 'void'}} -} - -namespace PR21947 { -int blue; // expected-note {{'blue' declared here}} -__typeof blur y; // expected-error {{use of undeclared identifier 'blur'; did you mean 'blue'?}} -} - -namespace PR22092 { -a = b ? : 0; // expected-error {{a type specifier is required for all declarations}} \ - // expected-error-re {{use of undeclared identifier 'b'{{$}}}} -} - -extern long clock (void); -struct Pointer { - void set_xpos(int); - void set_ypos(int); -}; -void MovePointer(Pointer &Click, int x, int y) { // expected-note 2 {{'Click' declared here}} - click.set_xpos(x); // expected-error {{use of undeclared identifier 'click'; did you mean 'Click'?}} - click.set_ypos(x); // expected-error {{use of undeclared identifier 'click'; did you mean 'Click'?}} -} - -namespace PR22250 { -// expected-error@+4 {{use of undeclared identifier 'size_t'; did you mean 'sizeof'?}} -// expected-error-re@+3 {{use of undeclared identifier 'y'{{$}}}} -// expected-error-re@+2 {{use of undeclared identifier 'z'{{$}}}} -// expected-error@+1 {{expected ';' after top level declarator}} -int getenv_s(size_t *y, char(&z)) {} -} - -namespace PR22291 { -template void f() { - unsigned *prio_bits_array; // expected-note {{'prio_bits_array' declared here}} - // expected-error@+1 {{use of undeclared identifier 'prio_op_array'; did you mean 'prio_bits_array'?}} - __atomic_store_n(prio_op_array + I, false, __ATOMIC_RELAXED); -} -} - -namespace PR22297 { -double pow(double x, double y); -struct TimeTicks { - static void Now(); // expected-note {{'Now' declared here}} -}; -void f() { - TimeTicks::now(); // expected-error {{no member named 'now' in 'PR22297::TimeTicks'; did you mean 'Now'?}} -} -} - -namespace PR23005 { -void f() { int a = Unknown::b(c); } // expected-error {{use of undeclared identifier 'Unknown'}} -// expected-error@-1 {{use of undeclared identifier 'c'}} -} - -namespace PR23350 { -int z = 1 ? N : ; // expected-error {{expected expression}} -// expected-error-re@-1 {{use of undeclared identifier 'N'{{$}}}} -} - -// PR 23285. This test must be at the end of the file to avoid additional, -// unwanted diagnostics. -// expected-error-re@+2 {{use of undeclared identifier 'uintmax_t'{{$}}}} -// expected-error@+1 {{expected ';' after top level declarator}} -unsigned int a = 0(uintmax_t diff --git a/clang/test/SemaCXX/typo-correction.cpp b/clang/test/SemaCXX/typo-correction.cpp index 45f42c4260358..e4dadf83e0a08 100644 --- a/clang/test/SemaCXX/typo-correction.cpp +++ b/clang/test/SemaCXX/typo-correction.cpp @@ -3,7 +3,6 @@ namespace PR21817{ int a(-rsing[2]); // expected-error {{undeclared identifier 'rsing'; did you mean 'using'?}} - // expected-error@-1 {{expected expression}} } struct errc { @@ -43,14 +42,14 @@ inline error_condition make_error_condition(errc _e) { // refer to a base class or non-static data member. struct BaseType { }; struct Derived : public BaseType { // expected-note {{base class 'BaseType' specified here}} - static int base_type; // expected-note {{'base_type' declared here}} + static int base_type; Derived() : basetype() {} // expected-error{{initializer 'basetype' does not name a non-static data member or base class; did you mean the base class 'BaseType'?}} }; // Test the improvement from passing a callback object to CorrectTypo in // the helper function LookupMemberExprInRecord. int get_type(struct Derived *st) { - return st->Base_Type; // expected-error{{no member named 'Base_Type' in 'Derived'; did you mean 'base_type'?}} + return st->Base_Type; // expected-error{{no member named 'Base_Type' in 'Derived'}} } // In this example, somename should not be corrected to the cached correction @@ -212,12 +211,11 @@ namespace PR13051 { }; void foo(); // expected-note{{'foo' declared here}} - void g(void(*)()); // expected-note{{candidate function not viable}} - void g(bool(S::*)() const); // expected-note{{candidate function not viable}} + void g(void(*)()); + void g(bool(S::*)() const); void test() { - g(&S::tempalte f); // expected-error{{did you mean 'template'?}} \ - // expected-error{{no matching function for call to 'g'}} + g(&S::tempalte f); // expected-error{{did you mean 'template'?}} g(&S::opeartor bool); // expected-error{{did you mean 'operator'?}} g(&S::foo); // expected-error{{no member named 'foo' in 'PR13051::S'; did you mean simply 'foo'?}} } @@ -251,13 +249,13 @@ namespace b6956809_test1 { struct S1 { void method(A*); // no note here - void method(B*); // expected-note{{'method' declared here}} + void method(B*); }; void test1() { B b; S1 s; - s.methodd(&b); // expected-error{{no member named 'methodd' in 'b6956809_test1::S1'; did you mean 'method'}} + s.methodd(&b); // expected-error{{no member named 'methodd' in 'b6956809_test1::S1'}} } struct S2 { @@ -275,15 +273,15 @@ namespace b6956809_test1 { } namespace b6956809_test2 { - template struct Err { typename T::error n; }; // expected-error{{type 'void *' cannot be used prior to '::' because it has no members}} + template struct Err { typename T::error n; }; struct S { - template typename Err::type method(T); // expected-note{{in instantiation of template class 'b6956809_test2::Err' requested here}} - template int method(T *); // expected-note{{'method' declared here}} + template typename Err::type method(T); + template int method(T *); }; void test() { S s; - int k = s.methodd((void*)0); // expected-error{{no member named 'methodd' in 'b6956809_test2::S'; did you mean 'method'?}} expected-note{{while substituting deduced template arguments into function template 'method' [with T = void *]}} + int k = s.methodd((void*)0); // expected-error{{no member named 'methodd' in 'b6956809_test2::S'}} } } @@ -309,12 +307,12 @@ struct A { void CreateBar(float, float); }; struct B : A { - using A::CreateFoo; // expected-note {{'CreateFoo' declared here}} - void CreateFoo(int, int); // expected-note {{'CreateFoo' declared here}} + using A::CreateFoo; + void CreateFoo(int, int); }; void f(B &x) { - x.Createfoo(0,0); // expected-error {{no member named 'Createfoo' in 'PR13387::B'; did you mean 'CreateFoo'?}} - x.Createfoo(0.f,0.f); // expected-error {{no member named 'Createfoo' in 'PR13387::B'; did you mean 'CreateFoo'?}} + x.Createfoo(0,0); // expected-error {{no member named 'Createfoo' in 'PR13387::B'}} + x.Createfoo(0.f,0.f); // expected-error {{no member named 'Createfoo' in 'PR13387::B'}} } } @@ -649,12 +647,12 @@ class AddObservation { // expected-note {{declared here}} namespace testNonStaticMemberHandling { struct Foo { - bool usesMetadata; // expected-note {{'usesMetadata' declared here}} + bool usesMetadata; }; int test(Foo f) { if (UsesMetadata) // expected-error-re {{use of undeclared identifier 'UsesMetadata'{{$}}}} return 5; - if (f.UsesMetadata) // expected-error {{no member named 'UsesMetadata' in 'testNonStaticMemberHandling::Foo'; did you mean 'usesMetadata'?}} + if (f.UsesMetadata) // expected-error {{no member named 'UsesMetadata' in 'testNonStaticMemberHandling::Foo'}} return 11; return 0; } @@ -707,7 +705,7 @@ using C::D::Foofoo; // expected-error {{no member named 'Foofoo' in namespace ' int d = ? L : d; // expected-error {{expected expression}} expected-error {{undeclared identifier}} struct B0 { - int : 0 | // expected-error {{invalid operands to binary expression}} + int : 0 | (struct B0)e; // expected-error {{use of undeclared identifier}} }; diff --git a/clang/test/SemaCXX/virtuals.cpp b/clang/test/SemaCXX/virtuals.cpp index 2a22ab9fc2b09..f6f52d51f650c 100644 --- a/clang/test/SemaCXX/virtuals.cpp +++ b/clang/test/SemaCXX/virtuals.cpp @@ -58,10 +58,8 @@ struct Base { }; struct Derived final : Base { - virtual ~Derived() = defaul; // #default + virtual ~Derived() = defaul; // expected-error {{use of undeclared identifier 'defaul'}} } do_not_crash; -// expected-error@#default {{initializer on function does not look like a pure-specifier}} -// expected-error@#default {{use of undeclared identifier 'defaul'}} } namespace VirtualFriend { diff --git a/clang/test/SemaObjC/call-super-2.m b/clang/test/SemaObjC/call-super-2.m index 01acff70c2301..885f392e353a6 100644 --- a/clang/test/SemaObjC/call-super-2.m +++ b/clang/test/SemaObjC/call-super-2.m @@ -115,7 +115,7 @@ @interface B : A @end @implementation B -- (instancetype)initWithCoder:(C *)coder { +- (instancetype)initWithCoder:(C *)coder { // expected-note {{'coder' declared here}} if (0 != (self = [super initWithCode:code])) // expected-error {{use of undeclared identifier 'code'}} expected-warning {{instance method '-initWithCode:' not found}} return (void *)0; return (void *)0; diff --git a/clang/test/SemaObjC/typo-correction-subscript.m b/clang/test/SemaObjC/typo-correction-subscript.m index 340f3cfe2743c..6c09127dbb8d6 100644 --- a/clang/test/SemaObjC/typo-correction-subscript.m +++ b/clang/test/SemaObjC/typo-correction-subscript.m @@ -7,8 +7,7 @@ @interface Test @implementation Test - (void)rdar47403222:(Dictionary *)opts { [self undeclaredMethod:undeclaredArg]; - // expected-error@-1{{no visible @interface for 'Test' declares the selector 'undeclaredMethod:'}} - // expected-error@-2{{use of undeclared identifier 'undeclaredArg}} + // expected-error@-1{{use of undeclared identifier 'undeclaredArg}} opts[(__bridge id)undeclaredKey] = 0; // expected-error@-1{{use of undeclared identifier 'undeclaredKey'}} } diff --git a/clang/test/SemaObjC/undef-arg-super-method-call.m b/clang/test/SemaObjC/undef-arg-super-method-call.m index 11fd97f2c00d8..b8cbe7f69f2f5 100644 --- a/clang/test/SemaObjC/undef-arg-super-method-call.m +++ b/clang/test/SemaObjC/undef-arg-super-method-call.m @@ -11,12 +11,12 @@ @interface DBGViewDebuggerSupport_iOS : DBGViewDebuggerSupport @end @implementation DBGViewDebuggerSupport_iOS -+ (void)addViewLayerInfo:(id)aView; // expected-note {{'aView' declared here}} ++ (void)addViewLayerInfo:(id)aView; { - [super addViewLayerInfo:view]; // expected-error {{use of undeclared identifier 'view'; did you mean 'aView'?}} + [super addViewLayerInfo:view]; // expected-error {{use of undeclared identifier 'view'}} } -- (void)addInstViewLayerInfo:(id)aView; // expected-note {{'aView' declared here}} +- (void)addInstViewLayerInfo:(id)aView; { - [super addInstViewLayerInfo:view]; // expected-error {{use of undeclared identifier 'view'; did you mean 'aView'?}} + [super addInstViewLayerInfo:view]; // expected-error {{use of undeclared identifier 'view'}} } @end diff --git a/clang/test/SemaObjCXX/block-for-lambda-conversion.mm b/clang/test/SemaObjCXX/block-for-lambda-conversion.mm index 671e83dc22019..a3bcfab677197 100644 --- a/clang/test/SemaObjCXX/block-for-lambda-conversion.mm +++ b/clang/test/SemaObjCXX/block-for-lambda-conversion.mm @@ -8,19 +8,20 @@ NSEventMaskLeftMouseDown = 1 }; -static const NSEventType NSFlagsChanged = NSEventTypeFlagsChanged; +static const NSEventType NSFlagsChanged = NSEventTypeFlagsChanged; // expected-note {{'NSFlagsChanged' declared here}} @interface NSObject @end @interface NSEvent : NSObject { } + (nullable id) -addMonitor:(NSEventMask)mask handler:(NSEvent *_Nullable (^)(NSEvent *))block; +addMonitor:(NSEventMask)mask handler:(NSEvent *_Nullable (^)(NSEvent *))block; // expected-note {{passing argument to parameter 'mask' here}} @end void test(id weakThis) { id m_flagsChangedEventMonitor = [NSEvent - addMonitor:NSFlagsChangedMask //expected-error {{use of undeclared identifier 'NSFlagsChangedMask'}} + addMonitor:NSFlagsChangedMask //expected-error {{use of undeclared identifier 'NSFlagsChangedMask'}} \ + expected-error {{cannot initialize a parameter of type 'NSEventMask' with an lvalue of type 'const NSEventType'}} handler:[weakThis](NSEvent *flagsChangedEvent) { return flagsChangedEvent; }]; diff --git a/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.cpp b/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.cpp index c6dbe4db2be64..0cf27666dd030 100644 --- a/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.cpp +++ b/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.cpp @@ -119,8 +119,7 @@ struct HasInt { template void TestInst() { - // expected-error@+2{{no member named 'Invalid' in 'HasInt'}} - // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}} + // expected-error@+1{{no member named 'Invalid' in 'HasInt'}} #pragma acc serial num_gangs(HasInt::Invalid) while(1); @@ -137,8 +136,7 @@ void TestInst() { #pragma acc parallel num_gangs(T::Invalid, 1) while(1); - // expected-error@+2{{no member named 'Invalid' in 'HasInt'}} - // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}} + // expected-error@+1{{no member named 'Invalid' in 'HasInt'}} #pragma acc serial num_gangs(1, HasInt::Invalid) while(1); diff --git a/clang/test/SemaOpenCL/atomic-ops.cl b/clang/test/SemaOpenCL/atomic-ops.cl index 7a273546db772..babebba31e82b 100644 --- a/clang/test/SemaOpenCL/atomic-ops.cl +++ b/clang/test/SemaOpenCL/atomic-ops.cl @@ -167,7 +167,7 @@ void syncscope_checks(atomic_int *Ap, int scope) { (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_all_devices); #if __OPENCL_C_VERSION__ < CL_VERSION_3_0 // expected-error@-2{{use of undeclared identifier 'memory_scope_all_devices'}} - // expected-note@* {{'memory_scope_all_svm_devices' declared here}} + // expected-note@opencl-c-base.h:*{{'memory_scope_all_svm_devices' declared here}} #endif (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_sub_group); (void)__opencl_atomic_load(Ap, memory_order_relaxed, scope); diff --git a/clang/test/SemaOpenCL/clang-builtin-version.cl b/clang/test/SemaOpenCL/clang-builtin-version.cl index ec6eecee3106c..21cbf2d8f28d4 100644 --- a/clang/test/SemaOpenCL/clang-builtin-version.cl +++ b/clang/test/SemaOpenCL/clang-builtin-version.cl @@ -17,12 +17,8 @@ kernel void dse_builtins(void) { }); #if (__OPENCL_C_VERSION__ >= CL_VERSION_3_0) && !defined(__opencl_c_device_enqueue) // expected-error@-10{{support disabled - compile with -fblocks or for OpenCL C 2.0 or OpenCL C 3.0 with __opencl_c_device_enqueue feature}} -// FIXME: the typo correction for the undeclared identifiers finds alternative -// suggestions, but instantiating the typo correction causes us to -// re-instantiate the argument to the call, which triggers the support -// diagnostic a second time. -// expected-error@-12 2{{support disabled - compile with -fblocks or for OpenCL C 2.0 or OpenCL C 3.0 with __opencl_c_device_enqueue feature}} -// expected-error@-10 2{{support disabled - compile with -fblocks or for OpenCL C 2.0 or OpenCL C 3.0 with __opencl_c_device_enqueue feature}} +// expected-error@-8 {{support disabled - compile with -fblocks or for OpenCL C 2.0 or OpenCL C 3.0 with __opencl_c_device_enqueue feature}} +// expected-error@-6 {{support disabled - compile with -fblocks or for OpenCL C 2.0 or OpenCL C 3.0 with __opencl_c_device_enqueue feature}} #endif } diff --git a/clang/test/SemaTemplate/concepts-recovery-expr.cpp b/clang/test/SemaTemplate/concepts-recovery-expr.cpp index b338f3bc271bf..6bed1790051f3 100644 --- a/clang/test/SemaTemplate/concepts-recovery-expr.cpp +++ b/clang/test/SemaTemplate/concepts-recovery-expr.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -std=c++20 -verify %s -// expected-error@+1{{use of undeclared identifier 'b'}} -constexpr bool CausesRecoveryExpr = b; +// expected-error@+1 {{invalid operands to binary expression ('const char[5]' and 'float')}} +constexpr bool CausesRecoveryExpr = "test" + 1.0f; template concept ReferencesCRE = CausesRecoveryExpr; diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp index a99df2390a551..62a4f95d79c74 100644 --- a/clang/test/SemaTemplate/concepts.cpp +++ b/clang/test/SemaTemplate/concepts.cpp @@ -814,11 +814,7 @@ static_assert(invalid also here ; // expected-error{{use of undeclared iden int foo() { bool b; - b = invalid not just in declarations; // expected-error{{expected ';' after expression}} - // expected-error@-1{{use of undeclared identifier 'invalid'}} - // expected-error@-2{{expected ';' after expression}} - // expected-error@-3{{use of undeclared identifier 'just'}} - // expected-error@-4{{unknown type name 'in'}} + b = invalid not just in declarations; // expected-error{{use of undeclared identifier 'invalid'}} return b; } } // namespace GH48182 diff --git a/clang/test/SemaTemplate/typo-variadic.cpp b/clang/test/SemaTemplate/typo-variadic.cpp index c9b777aebbe91..48306fb9ce805 100644 --- a/clang/test/SemaTemplate/typo-variadic.cpp +++ b/clang/test/SemaTemplate/typo-variadic.cpp @@ -1,2 +1,2 @@ // RUN: %clang_cc1 -fsyntax-only %s -verify -int x = m(s...); // expected-error{{pack expansion does not}} expected-error{{undeclared identifier}} +int x = m(s...); // expected-error{{undeclared identifier}} diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index 635d03a88d105..a6301daa672c3 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -598,7 +598,6 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent, case Stmt::SubstNonTypeTemplateParmPackExprClass: case Stmt::FunctionParmPackExprClass: case Stmt::UnresolvedLookupExprClass: - case Stmt::TypoExprClass: // A typo could actually be a DeclRef or a MemberRef K = CXCursor_DeclRefExpr; break; diff --git a/clang/unittests/Sema/ExternalSemaSourceTest.cpp b/clang/unittests/Sema/ExternalSemaSourceTest.cpp index 2b271d4bf7825..cc9dd4175af55 100644 --- a/clang/unittests/Sema/ExternalSemaSourceTest.cpp +++ b/clang/unittests/Sema/ExternalSemaSourceTest.cpp @@ -268,20 +268,6 @@ TEST(ExternalSemaSource, ExternalTypoCorrectionOrdering) { ASSERT_EQ(1, Watcher.SeenCount); } -TEST(ExternalSemaSource, ExternalDelayedTypoCorrection) { - auto Installer = std::make_unique(); - auto Provider = makeIntrusiveRefCnt("aaa", "bbb"); - DiagnosticWatcher Watcher("aaa", "bbb"); - Installer->PushSource(Provider.get()); - Installer->PushWatcher(&Watcher); - std::vector Args(1, "-std=c++11"); - ASSERT_TRUE(clang::tooling::runToolOnCodeWithArgs( - std::move(Installer), "namespace AAA { } void foo() { AAA::aaa(); }", - Args)); - ASSERT_LE(0, Provider->CallCount); - ASSERT_EQ(1, Watcher.SeenCount); -} - // We should only try MaybeDiagnoseMissingCompleteType if we can't otherwise // solve the problem. TEST(ExternalSemaSource, TryOtherTacticsBeforeDiagnosing) {