Merge "Fix invalid read of literal (anonymous) structure names on assertion builds."
diff --git a/include/bcc/Renderscript/RSUtils.h b/include/bcc/Renderscript/RSUtils.h
index edc7fdf..19b45f6 100644
--- a/include/bcc/Renderscript/RSUtils.h
+++ b/include/bcc/Renderscript/RSUtils.h
@@ -25,6 +25,34 @@
namespace {
static inline llvm::StringRef getUnsuffixedStructName(const llvm::StructType *T) {
+#ifdef FORCE_BUILD_LLVM_DISABLE_NDEBUG
+ // Bug: 22926131
+ // When building with assertions enabled, LLVM cannot read the name of a
+ // literal (anonymous) structure, because they shouldn't actually ever have
+ // a name. Unfortunately, due to past definitions of RenderScript object
+ // types as anonymous structures typedef-ed to their proper typename,
+ // we had been relying on accessing this information. LLVM bitcode retains
+ // the typedef-ed name for such anonymous structures. There is a
+ // corresponding (safe) fix to the RenderScript headers to actually name
+ // these types the same as their typedef name to simplify things. That
+ // fixes this issue going forward, but it won't allow us to compile legacy
+ // code properly. In that case, we just have non-assert builds ignore the
+ // fact that anonymous structures shouldn't have their name read, and do it
+ // anyway. Note that RSCompilerDriver.cpp checks the compiler version
+ // number (from llvm-rs-cc) to ensure that we are only ever building modern
+ // code when we have assertions enabled. Legacy code can only be compiled
+ // correctly with a non-asserting compiler.
+ //
+ // Note that the whole reason for looking at the "unsuffixed" name of the
+ // type is because LLVM suffixes duplicate typedefs of the same anonymous
+ // structure. In the new case, where all of the RS object types have a
+ // proper name, they won't have a dotted suffix at all. We still need
+ // to look at the old unsuffixed version to handle legacy code properly.
+ if (T->isLiteral()) {
+ return "";
+ }
+#endif
+
// Get just the object type name with no suffix.
size_t LastDot = T->getName().rfind('.');
if (LastDot == strlen("struct")) {
diff --git a/lib/Renderscript/RSCompilerDriver.cpp b/lib/Renderscript/RSCompilerDriver.cpp
index 7cc4ffb..fc69d50 100644
--- a/lib/Renderscript/RSCompilerDriver.cpp
+++ b/lib/Renderscript/RSCompilerDriver.cpp
@@ -265,6 +265,20 @@
script.setOptimizationLevel(static_cast<RSScript::OptimizationLevel>(
wrapper.getOptimizationLevel()));
+// Assertion-enabled builds can't compile legacy bitcode (due to the use of
+// getName() with anonymous structure definitions).
+#ifdef FORCE_BUILD_LLVM_DISABLE_NDEBUG
+ static const uint32_t kSlangMinimumFixedStructureNames = 2310;
+ uint32_t version = wrapper.getCompilerVersion();
+ if (version < kSlangMinimumFixedStructureNames) {
+ ALOGE("Found invalid legacy bitcode compiled with a version %u llvm-rs-cc "
+ "used with an assertion build", version);
+ ALOGE("Please recompile this apk with a more recent llvm-rs-cc "
+ "(at least %u)", kSlangMinimumFixedStructureNames);
+ return false;
+ }
+#endif
+
//===--------------------------------------------------------------------===//
// Compile the script
//===--------------------------------------------------------------------===//
diff --git a/libbcc-device-build.mk b/libbcc-device-build.mk
index 188f2f9..b103da2 100644
--- a/libbcc-device-build.mk
+++ b/libbcc-device-build.mk
@@ -39,6 +39,10 @@
LOCAL_CFLAGS += -D__DISABLE_ASSERTS
endif
+ifeq ($(FORCE_BUILD_LLVM_DISABLE_NDEBUG),true)
+LOCAL_CFLAGS += -DFORCE_BUILD_LLVM_DISABLE_NDEBUG
+endif
+
#=====================================================================
# Architecture Selection
#=====================================================================
diff --git a/libbcc-host-build.mk b/libbcc-host-build.mk
index 5dc69b7..9fe5278 100644
--- a/libbcc-host-build.mk
+++ b/libbcc-host-build.mk
@@ -28,6 +28,10 @@
LOCAL_CFLAGS += -D__DISABLE_ASSERTS
endif
+ifeq ($(FORCE_BUILD_LLVM_DISABLE_NDEBUG),true)
+LOCAL_CFLAGS += -DFORCE_BUILD_LLVM_DISABLE_NDEBUG
+endif
+
LOCAL_C_INCLUDES := \
$(LIBBCC_ROOT_PATH)/include \
$(RS_ROOT_PATH) \