Fix long-standing bug with multiple pragmas.

There is a subtle bug here in that the rs_fp_imprecise setting will always be
clobbered with rs_fp_full due to the "fast return" path. This change also
replaces ::strcmp() with the original implementation's std::string::compare().

Change-Id: I5b309583fed84d09ded091e25f1971fa9e1ec430
diff --git a/lib/Renderscript/RSInfo.cpp b/lib/Renderscript/RSInfo.cpp
index 0d8fd68..ff6a0a2 100644
--- a/lib/Renderscript/RSInfo.cpp
+++ b/lib/Renderscript/RSInfo.cpp
@@ -21,6 +21,7 @@
 
 #include <cstring>
 #include <new>
+#include <string>
 
 #include "bcc/Support/FileBase.h"
 #include "bcc/Support/Log.h"
@@ -319,33 +320,36 @@
 
 RSInfo::FloatPrecision RSInfo::getFloatPrecisionRequirement() const {
   // Check to see if we have any FP precision-related pragmas.
-  static const char relaxed_pragma[] = "rs_fp_relaxed";
-  static const char imprecise_pragma[] = "rs_fp_imprecise";
-  static const char full_pragma[] = "rs_fp_full";
+  std::string relaxed_pragma("rs_fp_relaxed");
+  std::string imprecise_pragma("rs_fp_imprecise");
+  std::string full_pragma("rs_fp_full");
   bool relaxed_pragma_seen = false;
-  RSInfo::FloatPrecision result;
+  bool imprecise_pragma_seen = false;
+  RSInfo::FloatPrecision result = FP_Full;
 
   for (PragmaListTy::const_iterator pragma_iter = mPragmas.begin(),
            pragma_end = mPragmas.end(); pragma_iter != pragma_end;
        pragma_iter++) {
     const char *pragma_key = pragma_iter->first;
-    if (::strcmp(pragma_key, relaxed_pragma) == 0) {
-      relaxed_pragma_seen = true;
-    } else if (::strcmp(pragma_key, imprecise_pragma) == 0) {
-      if (relaxed_pragma_seen) {
-        ALOGW("Multiple float precision pragmas specified!");
+    if (!relaxed_pragma.compare(pragma_key)) {
+      if (relaxed_pragma_seen || imprecise_pragma_seen) {
+        ALOGE("Multiple float precision pragmas specified!");
       }
-      // Fast return when there's rs_fp_imprecise specified.
-      result = FP_Imprecise;
+      relaxed_pragma_seen = true;
+    } else if (!imprecise_pragma.compare(pragma_key)) {
+      if (relaxed_pragma_seen || imprecise_pragma_seen) {
+        ALOGE("Multiple float precision pragmas specified!");
+      }
+      imprecise_pragma_seen = true;
     }
   }
 
   // Imprecise is selected over Relaxed precision.
   // In the absence of both, we stick to the default Full precision.
-  if (relaxed_pragma_seen) {
+  if (imprecise_pragma_seen) {
+    result = FP_Imprecise;
+  } else if (relaxed_pragma_seen) {
     result = FP_Relaxed;
-  } else {
-    result = FP_Full;
   }
 
   // Provide an override for precsion via adb shell setprop
@@ -356,13 +360,13 @@
   property_get("debug.rs.precision", precision_prop_buf, "");
 
   if (precision_prop_buf[0]) {
-    if (::strcmp(precision_prop_buf, relaxed_pragma) == 0) {
+    if (!relaxed_pragma.compare(precision_prop_buf)) {
       ALOGI("Switching to RS FP relaxed mode via setprop");
       result = FP_Relaxed;
-    } else if (::strcmp(precision_prop_buf, imprecise_pragma) == 0) {
+    } else if (!imprecise_pragma.compare(precision_prop_buf)) {
       ALOGI("Switching to RS FP imprecise mode via setprop");
       result = FP_Imprecise;
-    } else if (::strcmp(precision_prop_buf, full_pragma) == 0) {
+    } else if (!full_pragma.compare(precision_prop_buf)) {
       ALOGI("Switching to RS FP full mode via setprop");
       result = FP_Full;
     }