From 58c2ed20a28daf32644ce69bdfc1d181978a47aa Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Fri, 4 May 2018 21:39:25 +0000 Subject: [PATCH] [analyzer] pr37209: Fix casts of glvalues to references. Many glvalue expressions aren't of their respective reference type - they are simply glvalues of their value type. This was causing problems when we were trying to obtain type of the original expression while evaluating certain glvalue bit-casts. Fixed by artificially forging a reference type to provide to the casting procedure. Differential Revision: https://reviews.llvm.org/D46224 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@331558 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Core/ExprEngineC.cpp | 7 +++++++ test/Analysis/casts.cpp | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp index 5a306a5c5f..1221ddff76 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -257,6 +257,13 @@ ProgramStateRef ExprEngine::handleLValueBitCast( ProgramStateRef state, const Expr* Ex, const LocationContext* LCtx, QualType T, QualType ExTy, const CastExpr* CastE, StmtNodeBuilder& Bldr, ExplodedNode* Pred) { + if (T->isLValueReferenceType()) { + assert(!CastE->getType()->isLValueReferenceType()); + ExTy = getContext().getLValueReferenceType(ExTy); + } else if (T->isRValueReferenceType()) { + assert(!CastE->getType()->isRValueReferenceType()); + ExTy = getContext().getRValueReferenceType(ExTy); + } // Delegate to SValBuilder to process. SVal OrigV = state->getSVal(Ex, LCtx); SVal V = svalBuilder.evalCast(OrigV, T, ExTy); diff --git a/test/Analysis/casts.cpp b/test/Analysis/casts.cpp index f96f19b0ac..6499b20a79 100644 --- a/test/Analysis/casts.cpp +++ b/test/Analysis/casts.cpp @@ -21,3 +21,17 @@ void intAsBoolAsSwitchCondition(int c) { break; } } + +int *&castToIntPtrLValueRef(char *p) { + return (int *&)*(int *)p; +} +bool testCastToIntPtrLValueRef(char *p, int *s) { + return castToIntPtrLValueRef(p) != s; // no-crash +} + +int *&&castToIntPtrRValueRef(char *p) { + return (int *&&)*(int *)p; +} +bool testCastToIntPtrRValueRef(char *p, int *s) { + return castToIntPtrRValueRef(p) != s; // no-crash +} -- 2.40.0