Parcourir la source

No special case for unannotated params (#5094)

Initially the change here was forcing unannotated parameters to be
treated as uses (`in` parameters). Instead this changes to not handle
them explicitly.

Most `in` parameter uses should produce `LValueToRValue` casts which
will be identified as uses through other means, but by removing this
special case we can support unannotated AST nodes from generated ASTs
through this analysis based on their type and usage alone.

Fixes #5093
Chris B il y a 2 ans
Parent
commit
47958467cb

+ 3 - 4
tools/clang/lib/Analysis/UninitializedValues.cpp

@@ -496,11 +496,10 @@ void ClassifyRefs::VisitCallExpr(CallExpr *CE) {
       if (FD->getNumParams() > ParamIdx) {
         ParmVarDecl *PD = FD->getParamDecl(ParamIdx);
         bool HasIn = PD->hasAttr<HLSLInAttr>();
-        bool HasOut = PD->hasAttr<HLSLOutAttr>();
         bool HasInOut = PD->hasAttr<HLSLInOutAttr>();
-        // If we have an in annotation or no annotation (implcit in), this is a
-        // use not an initialization.
-        if(!HasOut || HasIn || HasInOut)
+        // If we have an explicit `in` or `inout` annotation we should treat
+        // this as a use, otherwise leave it up to C/C++ rules.
+        if(HasIn || HasInOut)
           classify(*I, Use);
       }
     }

+ 15 - 0
tools/clang/test/HLSL/out-param-diagnostics.hlsl

@@ -170,6 +170,21 @@ void MaybeUsedMaybeUnused([maybe_unused] out int Val, int Cnt) { // expected-not
     Val = 1;
 } // expected-note{{uninitialized use occurs here}}
 
+void Use(int V) {}
+
+void NoAnnotationIsUse(out int V) { // expected-note{{variable 'V' is declared here}}
+  Use(V); // expected-warning{{parameter 'V' is uninitialized when used here}}
+}
+
+RWByteAddressBuffer buffer;
+
+// No expected diagnostic here. InterlockedAdd is not annotated with HLSL
+// parameter annotations, so we fall back to C/C++ rules, which don't treat
+// reference passed parameters as uses.
+void interlockWrapper(out uint original) {
+  buffer.InterlockedAdd(16, 1, original);
+}
+
 // Neither of these will warn because we don't support element-based tracking.
 void UnusedSizedArray(out uint u[2]) { }
 void UnusedUnsizedArray(out uint u[]) { }