hokein created this revision. hokein added a reviewer: sammccall. Herald added a project: clang.
Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D84226 Files: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaOverload.cpp clang/test/AST/ast-dump-recovery.c clang/test/Sema/error-dependence.c
Index: clang/test/Sema/error-dependence.c =================================================================== --- /dev/null +++ clang/test/Sema/error-dependence.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -frecovery-ast -fno-recovery-ast-type %s + +int call(int); // expected-note {{'call' declared here}} + +void test1(int s) { + // verify "assigning to 'int' from incompatible type '<dependent type>'" is + // not emitted. + s = call(); // expected-error {{too few arguments to function call}} +} Index: clang/test/AST/ast-dump-recovery.c =================================================================== --- clang/test/AST/ast-dump-recovery.c +++ clang/test/AST/ast-dump-recovery.c @@ -42,11 +42,16 @@ void test2() { int* ptr; - // FIXME: the top-level expr should be a binary operator. - // CHECK: ImplicitCastExpr {{.*}} contains-errors <LValueToRValue> - // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors lvalue - // CHECK-NEXT: |-DeclRefExpr {{.*}} 'ptr' 'int *' - // CHECK-NEXT: `-RecoveryExpr {{.*}} - // CHECK-NEXT: `-DeclRefExpr {{.*}} 'some_func' + // CHECK: BinaryOperator {{.*}} contains-errors '=' + // CHECK-NEXT: |-DeclRefExpr {{.*}} 'ptr' 'int *' + // CHECK-NEXT: `-RecoveryExpr {{.*}} + // CHECK-NEXT: `-DeclRefExpr {{.*}} 'some_func' ptr = some_func(); // should not crash + + int compoundOp; + // CHECK: CompoundAssignOperator {{.*}} '+=' + // CHECK-NEXT: |-DeclRefExpr {{.*}} 'compoundOp' + // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors + // CHECK-NEXT: `-DeclRefExpr {{.*}} 'some_func' + compoundOp += some_func(); } Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -13288,18 +13288,8 @@ // If either side is type-dependent, create an appropriate dependent // expression. if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) { - if (Fns.empty()) { - // If there are no functions to store, just build a dependent - // BinaryOperator or CompoundAssignment. - if (Opc <= BO_Assign || Opc > BO_OrAssign) - return BinaryOperator::Create( - Context, Args[0], Args[1], Opc, Context.DependentTy, VK_RValue, - OK_Ordinary, OpLoc, CurFPFeatureOverrides()); - return CompoundAssignOperator::Create( - Context, Args[0], Args[1], Opc, Context.DependentTy, VK_LValue, - OK_Ordinary, OpLoc, CurFPFeatureOverrides(), Context.DependentTy, - Context.DependentTy); - } + if (Fns.empty()) + return CreateDependentBinOp(OpLoc, Opc, Args[0], Args[1]); // FIXME: save results of ADL from here? CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -14220,10 +14220,27 @@ return S.CreateOverloadedBinOp(OpLoc, Opc, Functions, LHS, RHS); } +ExprResult Sema::CreateDependentBinOp(SourceLocation OpLoc, + BinaryOperatorKind Opc, Expr *LHS, + Expr *RHS) { + assert(LHS->isTypeDependent() || RHS->isTypeDependent()); + // If there are no functions to store, just build a dependent + // BinaryOperator or CompoundAssignment. + if (Opc <= BO_Assign || Opc > BO_OrAssign) + return BinaryOperator::Create(Context, LHS, RHS, Opc, Context.DependentTy, + VK_RValue, OK_Ordinary, OpLoc, + CurFPFeatureOverrides()); + return CompoundAssignOperator::Create( + Context, LHS, RHS, Opc, Context.DependentTy, VK_LValue, OK_Ordinary, + OpLoc, CurFPFeatureOverrides(), Context.DependentTy, Context.DependentTy); +} + ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr) { ExprResult LHS, RHS; + // FIXME: this early typo correction can be removed now, since we support the + // dependent binary operator in C. std::tie(LHS, RHS) = CorrectDelayedTyposInBinOp(*this, Opc, LHSExpr, RHSExpr); if (!LHS.isUsable() || !RHS.isUsable()) return ExprError(); @@ -14322,6 +14339,13 @@ return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr); } + if (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent()) { + assert(!getLangOpts().CPlusPlus); + assert((LHSExpr->containsErrors() || RHSExpr->containsErrors()) && + "Should only occur in error-recovery path."); + return CreateDependentBinOp(OpLoc, Opc, LHSExpr, RHSExpr); + } + // Build a built-in binary operation. return CreateBuiltinBinOp(OpLoc, Opc, LHSExpr, RHSExpr); } Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -5157,6 +5157,8 @@ BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr); ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr); + ExprResult CreateDependentBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, + Expr *LHS, Expr *RHS); void DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits