Skip to content

Commit

Permalink
[Analyzer] Always use non-reference types when creating expressions i…
Browse files Browse the repository at this point in the history
…n 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
  • Loading branch information
George Karpenkov committed Oct 17, 2017
1 parent 9344e45 commit b2a60c6
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 23 deletions.
36 changes: 14 additions & 22 deletions clang/lib/Analysis/BodyFarm.cpp
Expand Up @@ -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);
Expand All @@ -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,
Expand Down Expand Up @@ -138,12 +136,10 @@ CompoundStmt *ASTMaker::makeCompound(ArrayRef<Stmt *> 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<VarDecl *>(D),
Expand All @@ -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);
}

Expand Down Expand Up @@ -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) {
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Analysis/call_once.cpp
Expand Up @@ -17,7 +17,7 @@ typedef struct once_flag_s {
#endif

template <class Callable, class... Args>
void call_once(once_flag &o, Callable func, Args... args) {};
void call_once(once_flag &o, Callable&& func, Args&&... args) {};

} // namespace std

Expand Down

0 comments on commit b2a60c6

Please sign in to comment.