[PATCH] D47628: Detect an incompatible VLA pointer assignment
Jeremy Morse via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 5 02:23:31 PDT 2018
This revision was automatically updated to reflect the committed changes.
jmorse marked 2 inline comments as done.
Closed by commit rL333989: Detect an incompatible VLA pointer assignment (authored by jmorse, committed by ).
Herald added a subscriber: llvm-commits.
Changed prior to commit:
https://reviews.llvm.org/D47628?vs=149688&id=149919#toc
Repository:
rL LLVM
https://reviews.llvm.org/D47628
Files:
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/test/Sema/vla.c
Index: cfe/trunk/test/Sema/vla.c
===================================================================
--- cfe/trunk/test/Sema/vla.c
+++ cfe/trunk/test/Sema/vla.c
@@ -76,3 +76,16 @@
];
};
int (*use_implicitly_declared)() = implicitly_declared; // ok, was implicitly declared at file scope
+
+void VLAPtrAssign(int size) {
+ int array[1][2][3][size][4][5];
+ // This is well formed
+ int (*p)[2][3][size][4][5] = array;
+ // Last array dimension too large
+ int (*p2)[2][3][size][4][6] = array; // expected-warning {{incompatible pointer types}}
+ // Second array dimension too large
+ int (*p3)[20][3][size][4][5] = array; // expected-warning {{incompatible pointer types}}
+
+ // Not illegal in C, program _might_ be well formed if size == 3.
+ int (*p4)[2][size][3][4][5] = array;
+}
Index: cfe/trunk/lib/AST/ASTContext.cpp
===================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp
+++ cfe/trunk/lib/AST/ASTContext.cpp
@@ -8601,16 +8601,46 @@
QualType ResultType = mergeTypes(LHSElem, RHSElem, false, Unqualified);
if (ResultType.isNull())
return {};
+
+ const VariableArrayType* LVAT = getAsVariableArrayType(LHS);
+ const VariableArrayType* RVAT = getAsVariableArrayType(RHS);
+
+ // If either side is a variable array, and both are complete, check whether
+ // the current dimension is definite.
+ if (LVAT || RVAT) {
+ auto SizeFetch = [this](const VariableArrayType* VAT,
+ const ConstantArrayType* CAT)
+ -> std::pair<bool,llvm::APInt> {
+ if (VAT) {
+ llvm::APSInt TheInt;
+ Expr *E = VAT->getSizeExpr();
+ if (E && E->isIntegerConstantExpr(TheInt, *this))
+ return std::make_pair(true, TheInt);
+ else
+ return std::make_pair(false, TheInt);
+ } else if (CAT) {
+ return std::make_pair(true, CAT->getSize());
+ } else {
+ return std::make_pair(false, llvm::APInt());
+ }
+ };
+
+ bool HaveLSize, HaveRSize;
+ llvm::APInt LSize, RSize;
+ std::tie(HaveLSize, LSize) = SizeFetch(LVAT, LCAT);
+ std::tie(HaveRSize, RSize) = SizeFetch(RVAT, RCAT);
+ if (HaveLSize && HaveRSize && !llvm::APInt::isSameValue(LSize, RSize))
+ return {}; // Definite, but unequal, array dimension
+ }
+
if (LCAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType))
return LHS;
if (RCAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType))
return RHS;
if (LCAT) return getConstantArrayType(ResultType, LCAT->getSize(),
ArrayType::ArraySizeModifier(), 0);
if (RCAT) return getConstantArrayType(ResultType, RCAT->getSize(),
ArrayType::ArraySizeModifier(), 0);
- const VariableArrayType* LVAT = getAsVariableArrayType(LHS);
- const VariableArrayType* RVAT = getAsVariableArrayType(RHS);
if (LVAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType))
return LHS;
if (RVAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType))
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D47628.149919.patch
Type: text/x-patch
Size: 3144 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180605/885951e2/attachment-0001.bin>
More information about the cfe-commits
mailing list