hokein updated this revision to Diff 355469. hokein added a comment. refine the solution: introduce a separate method, and call it when needed.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D104052/new/ https://reviews.llvm.org/D104052 Files: clang/include/clang/AST/Expr.h clang/lib/AST/Expr.cpp clang/lib/Sema/SemaExpr.cpp clang/test/SemaCXX/recovery-expr-type.cpp Index: clang/test/SemaCXX/recovery-expr-type.cpp =================================================================== --- clang/test/SemaCXX/recovery-expr-type.cpp +++ clang/test/SemaCXX/recovery-expr-type.cpp @@ -139,6 +139,7 @@ namespace test12 { // Verify we do not crash. -void fun(int *foo = no_such_function()); // expected-error {{undeclared identifier}} -void baz() { fun(); } +int fun(int *foo = no_such_function()); // expected-error {{undeclared identifier}} +void crash1() { fun(); } +void crash2() { constexpr int s = fun(); } } // namespace test12 Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -5924,6 +5924,7 @@ for (unsigned i = 0; i < TotalNumArgs; ++i) Call->setArg(i, AllArgs[i]); + Call->computeDependence(); return false; } @@ -6836,6 +6837,7 @@ TheCall->setArg(i, Arg); } + TheCall->computeDependence(); } if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(FDecl)) Index: clang/lib/AST/Expr.cpp =================================================================== --- clang/lib/AST/Expr.cpp +++ clang/lib/AST/Expr.cpp @@ -1398,7 +1398,7 @@ for (unsigned I = Args.size(); I != NumArgs; ++I) setArg(I, nullptr); - setDependence(computeDependence(this, PreArgs)); + this->computeDependence(); CallExprBits.HasFPFeatures = FPFeatures.requiresTrailingStorage(); if (hasStoredFPFeatures()) Index: clang/include/clang/AST/Expr.h =================================================================== --- clang/include/clang/AST/Expr.h +++ clang/include/clang/AST/Expr.h @@ -2987,11 +2987,21 @@ } /// setArg - Set the specified argument. + /// ! the dependence bits might be stale after calling this setter, it is + /// *caller*'s responsibility to recompute them. void setArg(unsigned Arg, Expr *ArgExpr) { assert(Arg < getNumArgs() && "Arg access out of range!"); getArgs()[Arg] = ArgExpr; } + /// Compute and set dependence bits. + void computeDependence() { + setDependence(clang::computeDependence( + this, llvm::makeArrayRef( + reinterpret_cast<Expr **>(getTrailingStmts() + PREARGS_START), + getNumPreArgs()))); + } + /// Reduce the number of arguments in this call expression. This is used for /// example during error recovery to drop extra arguments. There is no way /// to perform the opposite because: 1.) We don't track how much storage
Index: clang/test/SemaCXX/recovery-expr-type.cpp =================================================================== --- clang/test/SemaCXX/recovery-expr-type.cpp +++ clang/test/SemaCXX/recovery-expr-type.cpp @@ -139,6 +139,7 @@ namespace test12 { // Verify we do not crash. -void fun(int *foo = no_such_function()); // expected-error {{undeclared identifier}} -void baz() { fun(); } +int fun(int *foo = no_such_function()); // expected-error {{undeclared identifier}} +void crash1() { fun(); } +void crash2() { constexpr int s = fun(); } } // namespace test12 Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -5924,6 +5924,7 @@ for (unsigned i = 0; i < TotalNumArgs; ++i) Call->setArg(i, AllArgs[i]); + Call->computeDependence(); return false; } @@ -6836,6 +6837,7 @@ TheCall->setArg(i, Arg); } + TheCall->computeDependence(); } if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(FDecl)) Index: clang/lib/AST/Expr.cpp =================================================================== --- clang/lib/AST/Expr.cpp +++ clang/lib/AST/Expr.cpp @@ -1398,7 +1398,7 @@ for (unsigned I = Args.size(); I != NumArgs; ++I) setArg(I, nullptr); - setDependence(computeDependence(this, PreArgs)); + this->computeDependence(); CallExprBits.HasFPFeatures = FPFeatures.requiresTrailingStorage(); if (hasStoredFPFeatures()) Index: clang/include/clang/AST/Expr.h =================================================================== --- clang/include/clang/AST/Expr.h +++ clang/include/clang/AST/Expr.h @@ -2987,11 +2987,21 @@ } /// setArg - Set the specified argument. + /// ! the dependence bits might be stale after calling this setter, it is + /// *caller*'s responsibility to recompute them. void setArg(unsigned Arg, Expr *ArgExpr) { assert(Arg < getNumArgs() && "Arg access out of range!"); getArgs()[Arg] = ArgExpr; } + /// Compute and set dependence bits. + void computeDependence() { + setDependence(clang::computeDependence( + this, llvm::makeArrayRef( + reinterpret_cast<Expr **>(getTrailingStmts() + PREARGS_START), + getNumPreArgs()))); + } + /// Reduce the number of arguments in this call expression. This is used for /// example during error recovery to drop extra arguments. There is no way /// to perform the opposite because: 1.) We don't track how much storage
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits