From b2a60c6a9bf1421a1218c6753a2cdc8b4f3ffce9 Mon Sep 17 00:00:00 2001 From: George Karpenkov Date: Tue, 17 Oct 2017 22:28:18 +0000 Subject: [PATCH] [Analyzer] Always use non-reference types when creating expressions in BodyFarm. Remove an option to use a reference type (on by default!) since a non-reference type is always needed for creating expressions, functions with multiple boolean parameters are very hard to use, and in general it was just a booby trap for further crashes. Furthermore, generalize call_once test case to fix some of the crashes mentioned https://bugs.llvm.org/show_bug.cgi?id=34869 Also removes std::call_once crash. Differential Revision: https://reviews.llvm.org/D39015 llvm-svn: 316041 --- clang/lib/Analysis/BodyFarm.cpp | 36 ++++++++++++------------------- clang/test/Analysis/call_once.cpp | 2 +- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/clang/lib/Analysis/BodyFarm.cpp b/clang/lib/Analysis/BodyFarm.cpp index ae89350aac4f5..9568ec7519b55 100644 --- a/clang/lib/Analysis/BodyFarm.cpp +++ b/clang/lib/Analysis/BodyFarm.cpp @@ -63,8 +63,7 @@ class ASTMaker { /// Create a new DeclRefExpr for the referenced variable. DeclRefExpr *makeDeclRefExpr(const VarDecl *D, - bool RefersToEnclosingVariableOrCapture = false, - bool GetNonReferenceType = false); + bool RefersToEnclosingVariableOrCapture = false); /// Create a new UnaryOperator representing a dereference. UnaryOperator *makeDereference(const Expr *Arg, QualType Ty); @@ -82,8 +81,7 @@ class ASTMaker { /// DeclRefExpr in the process. ImplicitCastExpr * makeLvalueToRvalue(const VarDecl *Decl, - bool RefersToEnclosingVariableOrCapture = false, - bool GetNonReferenceType = false); + bool RefersToEnclosingVariableOrCapture = false); /// Create an implicit cast of the given type. ImplicitCastExpr *makeImplicitCast(const Expr *Arg, QualType Ty, @@ -138,12 +136,10 @@ CompoundStmt *ASTMaker::makeCompound(ArrayRef Stmts) { return new (C) CompoundStmt(C, Stmts, SourceLocation(), SourceLocation()); } -DeclRefExpr *ASTMaker::makeDeclRefExpr(const VarDecl *D, - bool RefersToEnclosingVariableOrCapture, - bool GetNonReferenceType) { - auto Type = D->getType(); - if (GetNonReferenceType) - Type = Type.getNonReferenceType(); +DeclRefExpr *ASTMaker::makeDeclRefExpr( + const VarDecl *D, + bool RefersToEnclosingVariableOrCapture) { + QualType Type = D->getType().getNonReferenceType(); DeclRefExpr *DR = DeclRefExpr::Create( C, NestedNameSpecifierLoc(), SourceLocation(), const_cast(D), @@ -162,14 +158,10 @@ ImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *Arg, QualType Ty) { ImplicitCastExpr * ASTMaker::makeLvalueToRvalue(const VarDecl *Arg, - bool RefersToEnclosingVariableOrCapture, - bool GetNonReferenceType) { - auto Type = Arg->getType(); - if (GetNonReferenceType) - Type = Type.getNonReferenceType(); + bool RefersToEnclosingVariableOrCapture) { + QualType Type = Arg->getType().getNonReferenceType(); return makeLvalueToRvalue(makeDeclRefExpr(Arg, - RefersToEnclosingVariableOrCapture, - GetNonReferenceType), + RefersToEnclosingVariableOrCapture), Type); } @@ -365,12 +357,13 @@ static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) { // Lambda requires callback itself inserted as a first parameter. CallArgs.push_back( M.makeDeclRefExpr(Callback, - /* RefersToEnclosingVariableOrCapture= */ true, - /* GetNonReferenceType= */ true)); + /* RefersToEnclosingVariableOrCapture= */ true)); // All arguments past first two ones are passed to the callback. for (unsigned int i = 2; i < D->getNumParams(); i++) - CallArgs.push_back(M.makeLvalueToRvalue(D->getParamDecl(i))); + CallArgs.push_back( + M.makeLvalueToRvalue(D->getParamDecl(i), + /* RefersToEnclosingVariableOrCapture= */ false)); CallExpr *CallbackCall; if (isLambdaCall) { @@ -385,8 +378,7 @@ static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) { DeclRefExpr *FlagDecl = M.makeDeclRefExpr(Flag, - /* RefersToEnclosingVariableOrCapture=*/true, - /* GetNonReferenceType=*/true); + /* RefersToEnclosingVariableOrCapture=*/true); MemberExpr *Deref = M.makeMemberExpression(FlagDecl, FlagFieldDecl); diff --git a/clang/test/Analysis/call_once.cpp b/clang/test/Analysis/call_once.cpp index 1881551096655..befddca752923 100644 --- a/clang/test/Analysis/call_once.cpp +++ b/clang/test/Analysis/call_once.cpp @@ -17,7 +17,7 @@ typedef struct once_flag_s { #endif template -void call_once(once_flag &o, Callable func, Args... args) {}; +void call_once(once_flag &o, Callable&& func, Args&&... args) {}; } // namespace std