Bug 1349417 - Placement new should preserve safety, r?bhackett draft
authorSteve Fink <sfink@mozilla.com>
Fri, 21 Apr 2017 17:12:07 -0700
changeset 566707 23cd60e1d75a3bce5ed658106671d6163731405b
parent 566706 44ffc0867fbb501413696457535f3165cb26ef1f
child 625392 fb3862639f14f3c69ff4177126076c867d0c57cc
push id55300
push userbmo:sphink@gmail.com
push dateSat, 22 Apr 2017 00:22:57 +0000
reviewersbhackett
bugs1349417
milestone55.0a1
Bug 1349417 - Placement new should preserve safety, r?bhackett MozReview-Commit-ID: 7bRj24L7Qqx
js/src/devtools/rootAnalysis/analyzeHeapWrites.js
--- a/js/src/devtools/rootAnalysis/analyzeHeapWrites.js
+++ b/js/src/devtools/rootAnalysis/analyzeHeapWrites.js
@@ -1061,41 +1061,54 @@ function isSafeVariable(entry, variable)
         // Hopefully the construction code doesn't leak pointers to the object
         // to places where other threads might access it.
         if (isDirectCall(edge, /operator new/) ||
             isDirectCall(edge, /nsCSSValue::Array::Create/))
         {
             return true;
         }
 
-        // References to the contents of an array are threadsafe if the array
-        // itself is threadsafe.
-        if ((isDirectCall(edge, /operator\[\]/) ||
-             isDirectCall(edge, /nsStyleContent::ContentAt/)) &&
-            isEdgeSafeArgument(entry, edge.PEdgeCallInstance.Exp))
-        {
-            return true;
-        }
-
-        // Watch for the coerced result of a getter_AddRefs call.
-        if (isDirectCall(edge, /operator /)) {
-            var otherEdge = expressionValueEdge(edge.PEdgeCallInstance.Exp);
-            if (otherEdge &&
-                isDirectCall(otherEdge, /getter_AddRefs/) &&
-                isEdgeSafeArgument(entry, otherEdge.PEdgeCallArguments.Exp[0]))
+        if ("PEdgeCallInstance" in edge) {
+            // References to the contents of an array are threadsafe if the array
+            // itself is threadsafe.
+            if ((isDirectCall(edge, /operator\[\]/) ||
+                 isDirectCall(edge, /nsStyleContent::ContentAt/)) &&
+                isEdgeSafeArgument(entry, edge.PEdgeCallInstance.Exp))
             {
                 return true;
             }
-        }
+
+            // Watch for the coerced result of a getter_AddRefs call.
+            if (isDirectCall(edge, /operator /)) {
+                var otherEdge = expressionValueEdge(edge.PEdgeCallInstance.Exp);
+                if (otherEdge &&
+                    isDirectCall(otherEdge, /getter_AddRefs/) &&
+                    isEdgeSafeArgument(entry, otherEdge.PEdgeCallArguments.Exp[0]))
+                {
+                    return true;
+                }
+            }
 
-        // Coercion via AsAString preserves safety.
-        if (isDirectCall(edge, /AsAString/) &&
-            isEdgeSafeArgument(entry, edge.PEdgeCallInstance.Exp))
-        {
-            return true;
+            // Placement-new returns a pointer that is as safe as the pointer
+            // passed to it. Exp[0] is the size, Exp[1] is the pointer/address.
+            // Note that the invocation of the constructor is a separate call,
+            // and so need not be considered here.
+            if (isDirectCall(edge, /operator new/) &&
+                edge.PEdgeCallInstance.Exp.length == 2 &&
+                isEdgeSafeArgument(entry, edge.PEdgeCallInstance.Exp[1]))
+            {
+                return true;
+            }
+
+            // Coercion via AsAString preserves safety.
+            if (isDirectCall(edge, /AsAString/) &&
+                isEdgeSafeArgument(entry, edge.PEdgeCallInstance.Exp))
+            {
+                return true;
+            }
         }
 
         // Watch out for variables which were assigned arguments.
         var rhsVariable = variableAssignRhs(edge);
         if (rhsVariable)
             return isSafeVariable(entry, rhsVariable);
     }