[clang] [clang] Improve diagnostics with incompatible VLA types (PR #101261)

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 31 10:20:07 PDT 2024


================
@@ -16644,7 +16644,32 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
     if (Action == AA_Passing_CFAudited) {
       DiagKind = diag::err_arc_typecheck_convert_incompatible_pointer;
     } else if (getLangOpts().CPlusPlus) {
-      DiagKind = diag::err_typecheck_convert_incompatible_pointer;
+      DiagKind = [this, &SrcType, &DstType] {
+        const VariableArrayType *SrcTypeVLA = nullptr, *DstTypeVLA = nullptr;
+        if (const PointerType *P = SrcType->getAs<PointerType>())
+          SrcTypeVLA = Context.getAsVariableArrayType(P->getPointeeType());
+        if (const PointerType *P = DstType->getAs<PointerType>())
+          DstTypeVLA = Context.getAsVariableArrayType(P->getPointeeType());
+
+        if (SrcTypeVLA == nullptr || DstTypeVLA == nullptr)
+          return diag::err_typecheck_convert_incompatible_pointer;
+
+        DeclRefExpr *SrcSizeExpr = nullptr, *DstSizeExpr = nullptr;
+        if (ImplicitCastExpr *I =
+                dyn_cast<ImplicitCastExpr>(SrcTypeVLA->getSizeExpr()))
+          SrcSizeExpr = dyn_cast<DeclRefExpr>(I->getSubExpr());
+        if (ImplicitCastExpr *I =
+                dyn_cast<ImplicitCastExpr>(DstTypeVLA->getSizeExpr()))
+          DstSizeExpr = dyn_cast<DeclRefExpr>(I->getSubExpr());
+
+        if (SrcSizeExpr == nullptr || DstSizeExpr == nullptr)
+          return diag::err_typecheck_convert_incompatible_pointer;
+
+        return SrcSizeExpr->getDecl()->getName() ==
+                       DstSizeExpr->getDecl()->getName()
----------------
AaronBallman wrote:

I think it would be good to have a comment here explaining that comparing declaration *names* is intentional because you can have code with the same size expression names but differing declarations. e.g., https://godbolt.org/z/sTqoKrs1j

But, the downside to this is that it's only worried about `DeclRefExpr`s, but there can still be other situations like `MemberExpr` (https://godbolt.org/z/ET8fMG6aT) or `CallExpr` (https://godbolt.org/z/hxc8G1494), etc.

That's why I'm hoping we can find *some* way to handle this from the diagnostics engine. If the two types print to the same string, it would be nice to find some way to alert the user "these types are spelled the same way but are potentially unique types".

https://github.com/llvm/llvm-project/pull/101261


More information about the cfe-commits mailing list