[clang] [clang-tools-extra] [CLANGD] Do not crash on designator initialization of union (PR #83369)

via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 28 19:09:42 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-tools-extra
@llvm/pr-subscribers-clangd

@llvm/pr-subscribers-clang

Author: None (alirezamoshtaghi)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/83369.diff


2 Files Affected:

- (added) clang-tools-extra/clangd/test/designator_init.test (+31) 
- (modified) clang/lib/AST/Expr.cpp (+12-2) 


``````````diff
diff --git a/clang-tools-extra/clangd/test/designator_init.test b/clang-tools-extra/clangd/test/designator_init.test
new file mode 100644
index 00000000000000..739f2bfab54bcf
--- /dev/null
+++ b/clang-tools-extra/clangd/test/designator_init.test
@@ -0,0 +1,31 @@
+//# RUN: rm -rf %t.dir/* && mkdir -p %t.dir
+//# RUN: echo '[{"directory": "%/t.dir", "command": "clang -x c -c %s", "file": "%s"}]' > %t.dir/compile_commands.json
+//# RUN: clangd --compile-commands-dir=%t.dir --check=%s 2>&1 | FileCheck %s
+
+typedef struct S {
+  unsigned char id;
+  union {
+    unsigned int mask;
+    struct {
+      unsigned int unused:10;
+      unsigned int reserved:3;
+      unsigned int rest:19;
+    };
+  };
+} __attribute__((packed)) S_t;
+
+typedef struct H {
+  unsigned char hid;
+  unsigned int val;
+} handler_t;
+
+struct S
+get_foo (handler_t *h)
+{
+  S_t retval =
+    {.id=h->hid,
+     .mask=h->val};
+  return retval;
+}
+
+// CHECK: All checks completed, 0 errors
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index b4de2155adcebd..33eeeda89fe7a5 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -4601,11 +4601,21 @@ SourceRange DesignatedInitExpr::getDesignatorsSourceRange() const {
 SourceLocation DesignatedInitExpr::getBeginLoc() const {
   auto *DIE = const_cast<DesignatedInitExpr *>(this);
   Designator &First = *DIE->getDesignator(0);
-  if (First.isFieldDesignator())
-    return GNUSyntax ? First.getFieldLoc() : First.getDotLoc();
+  if (First.isFieldDesignator()) {
+    /* search all designators in case the first one is not
+       initialized */
+    for (unsigned int i=0; i<DIE->size(); i++) {
+      Designator &Des = *DIE->getDesignator(i);
+      SourceLocation retval = GNUSyntax ? Des.getFieldLoc() : Des.getDotLoc();
+      if (!retval.isValid ())
+	continue;
+      return retval;
+    }
+  }
   return First.getLBracketLoc();
 }
 
+
 SourceLocation DesignatedInitExpr::getEndLoc() const {
   return getInit()->getEndLoc();
 }

``````````

</details>


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


More information about the cfe-commits mailing list