[PATCH] D50050: [AST] CastExpr: BasePathSize is not large enough.
Roman Lebedev via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 31 04:10:12 PDT 2018
lebedev.ri created this revision.
lebedev.ri added reviewers: rjmccall, rsmith, erichkeane.
https://reviews.llvm.org/rC337815 / https://reviews.llvm.org/D49508 had to cannibalize one bit of `CastExprBitfields::BasePathSize` in order to squeeze `PartOfExplicitCast` boolean.
That reduced the maximal value of `PartOfExplicitCast` from 9 bits (~512) down to 8 bits (~256).
Apparently, that mattered. Too bad there weren't any tests.
It caused PR38356 <https://bugs.llvm.org/show_bug.cgi?id=38356>.
So we need to increase `PartOfExplicitCast` back at least to 9 bits, or a bit more.
For obvious reasons, we can't do that in `CastExprBitfields` - that would blow up the size of every `Expr`.
So we need to either just add a variable into the `CastExpr` (as done here),
or use `llvm::TrailingObjects`. The latter does not seem to be straight-forward.
Perhaps, that needs to be done not for the `CastExpr` itself, but for all of it's `final` children.
Repository:
rC Clang
https://reviews.llvm.org/D50050
Files:
include/clang/AST/Expr.h
include/clang/AST/Stmt.h
test/CodeGenCXX/castexpr-basepathsize-threshold.cpp
Index: test/CodeGenCXX/castexpr-basepathsize-threshold.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/castexpr-basepathsize-threshold.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -emit-llvm -o -
+
+// https://bugs.llvm.org/show_bug.cgi?id=38356
+// We only check that we do not crash.
+
+template <typename a, a b(unsigned), int c, unsigned...>
+struct d : d<a, b, c - 1> {};
+template <typename a, a b(unsigned), unsigned... e>
+struct d<a, b, 0, e...> {
+ a f[0];
+};
+struct g {
+ static g h(unsigned);
+};
+struct i {
+ void j() const;
+ // Current maximum depth of recursive template instantiation is 1024,
+ // thus, this \/ threshold value is used here. BasePathSize in CastExpr might
+ // not fit it, so we are testing that we do fit it.
+ // If -ftemplate-depth= is provided, larger values (4096 and up) cause crashes
+ // elsewhere.
+ d<g, g::h, (1U << 10U) - 2U> f;
+};
+void i::j() const {
+ const void *k{f.f};
+ (void)k;
+}
Index: include/clang/AST/Stmt.h
===================================================================
--- include/clang/AST/Stmt.h
+++ include/clang/AST/Stmt.h
@@ -204,7 +204,6 @@
unsigned Kind : 6;
unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr.
- unsigned BasePathSize : 32 - 6 - 1 - NumExprBits;
};
class CallExprBitfields {
Index: include/clang/AST/Expr.h
===================================================================
--- include/clang/AST/Expr.h
+++ include/clang/AST/Expr.h
@@ -2790,17 +2790,21 @@
private:
Stmt *Op;
+ // BasePathSize needs to have width of 9 bits (or more, up to 14(?) bits),
+ // so it does not fit into CastExprBitfields, where we only have 8 bits left.
+ unsigned BasePathSize : 14;
+
bool CastConsistency() const;
const CXXBaseSpecifier * const *path_buffer() const {
return const_cast<CastExpr*>(this)->path_buffer();
}
CXXBaseSpecifier **path_buffer();
void setBasePathSize(unsigned basePathSize) {
- CastExprBits.BasePathSize = basePathSize;
- assert(CastExprBits.BasePathSize == basePathSize &&
- "basePathSize doesn't fit in bits of CastExprBits.BasePathSize!");
+ BasePathSize = basePathSize;
+ assert(BasePathSize == basePathSize &&
+ "basePathSize doesn't fit in bits of BasePathSize!");
}
protected:
@@ -2859,8 +2863,8 @@
typedef CXXBaseSpecifier **path_iterator;
typedef const CXXBaseSpecifier * const *path_const_iterator;
- bool path_empty() const { return CastExprBits.BasePathSize == 0; }
- unsigned path_size() const { return CastExprBits.BasePathSize; }
+ bool path_empty() const { return BasePathSize == 0; }
+ unsigned path_size() const { return BasePathSize; }
path_iterator path_begin() { return path_buffer(); }
path_iterator path_end() { return path_buffer() + path_size(); }
path_const_iterator path_begin() const { return path_buffer(); }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D50050.158207.patch
Type: text/x-patch
Size: 2936 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180731/5845d670/attachment-0001.bin>
More information about the cfe-commits
mailing list