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) \