[PATCH] D52957: [analyzer] Teach CallEvent about C++17 aligned new.
Phabricator via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 15 10:55:19 PDT 2018
This revision was automatically updated to reflect the committed changes.
Closed by commit rL344539: [analyzer] Teach CallEvent about C++17 aligned operator new(). (authored by dergachev, committed by ).
Herald added subscribers: llvm-commits, donat.nagy.
Changed prior to commit:
https://reviews.llvm.org/D52957?vs=168556&id=169726#toc
Repository:
rL LLVM
https://reviews.llvm.org/D52957
Files:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
cfe/trunk/test/Analysis/new-aligned.cpp
Index: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
===================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -921,15 +921,28 @@
return getOriginExpr()->getOperatorNew();
}
+ // Size and maybe implicit alignment in C++17. Instead of size, the AST
+ // contains the construct-expression. Alignment is always hidden.
+ // We pretend that argument 0 is size and argument 1 is alignment (if passed
+ // implicitly) and the rest are placement args. This makes sure that the
+ // number of arguments is always the same as the number of parameters.
+ unsigned getNumImplicitArgs() const {
+ return getOriginExpr()->passAlignment() ? 2 : 1;
+ }
+
unsigned getNumArgs() const override {
- return getOriginExpr()->getNumPlacementArgs() + 1;
+ return getOriginExpr()->getNumPlacementArgs() + getNumImplicitArgs();
}
const Expr *getArgExpr(unsigned Index) const override {
// The first argument of an allocator call is the size of the allocation.
- if (Index == 0)
+ if (Index < getNumImplicitArgs())
return nullptr;
- return getOriginExpr()->getPlacementArg(Index - 1);
+ return getOriginExpr()->getPlacementArg(Index - getNumImplicitArgs());
+ }
+
+ const Expr *getPlacementArgExpr(unsigned Index) const {
+ return getOriginExpr()->getPlacementArg(Index);
}
Kind getKind() const override { return CE_CXXAllocator; }
Index: cfe/trunk/test/Analysis/new-aligned.cpp
===================================================================
--- cfe/trunk/test/Analysis/new-aligned.cpp
+++ cfe/trunk/test/Analysis/new-aligned.cpp
@@ -0,0 +1,14 @@
+//RUN: %clang_analyze_cc1 -std=c++17 -analyze -analyzer-checker=core -verify %s
+
+// expected-no-diagnostics
+
+// Notice the weird alignment.
+struct alignas(1024) S {};
+
+void foo() {
+ // Operator new() here is the C++17 aligned new that takes two arguments:
+ // size and alignment. Size is passed implicitly as usual, and alignment
+ // is passed implicitly in a similar manner.
+ S *s = new S; // no-warning
+ delete s;
+}
Index: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
===================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -503,10 +503,14 @@
const ParmVarDecl *ParamDecl = *I;
assert(ParamDecl && "Formal parameter has no decl?");
+ // TODO: Support allocator calls.
if (Call.getKind() != CE_CXXAllocator)
if (Call.isArgumentConstructedDirectly(Idx))
continue;
+ // TODO: Allocators should receive the correct size and possibly alignment,
+ // determined in compile-time but not represented as arg-expressions,
+ // which makes getArgSVal() fail and return UnknownVal.
SVal ArgVal = Call.getArgSVal(Idx);
if (!ArgVal.isUnknown()) {
Loc ParamLoc = SVB.makeLoc(MRMgr.getVarRegion(ParamDecl, CalleeCtx));
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D52957.169726.patch
Type: text/x-patch
Size: 3096 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20181015/c191ffa0/attachment-0001.bin>
More information about the cfe-commits
mailing list