[clang] [clang-tools-extra] [CLANGD] Do not crash on designator initialization of union (PR #83369)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 5 00:05:37 PST 2024
https://github.com/alirezamoshtaghi updated https://github.com/llvm/llvm-project/pull/83369
>From 3d6afe011221ac239bb668b375ed3f6c356fc47d Mon Sep 17 00:00:00 2001
From: alirezamoshtaghi <alireza.moshtaghi at gmail.com>
Date: Wed, 28 Feb 2024 13:55:11 -0800
Subject: [PATCH 1/3] [CLANGD] Do not crash on designator initialization of
union
---
.../clangd/test/designator_init.test | 31 +++++++++++++++++++
clang/lib/AST/Expr.cpp | 14 +++++++--
2 files changed, 43 insertions(+), 2 deletions(-)
create mode 100644 clang-tools-extra/clangd/test/designator_init.test
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();
}
>From 397f6cd893a6a07426d39f1dabd7ad27282435af Mon Sep 17 00:00:00 2001
From: alirezamoshtaghi <alireza.moshtaghi at gmail.com>
Date: Mon, 4 Mar 2024 11:54:56 -0800
Subject: [PATCH 2/3] fix formatting errors
---
clang/lib/AST/Expr.cpp | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 33eeeda89fe7a5..2e7170ecac0618 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -4602,20 +4602,17 @@ SourceLocation DesignatedInitExpr::getBeginLoc() const {
auto *DIE = const_cast<DesignatedInitExpr *>(this);
Designator &First = *DIE->getDesignator(0);
if (First.isFieldDesignator()) {
- /* search all designators in case the first one is not
- initialized */
- for (unsigned int i=0; i<DIE->size(); i++) {
+ 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;
+ if (!retval.isValid())
+ continue;
return retval;
}
}
return First.getLBracketLoc();
}
-
SourceLocation DesignatedInitExpr::getEndLoc() const {
return getInit()->getEndLoc();
}
>From d1d1458809e0b27dc05c70ef449ebbe6896437d4 Mon Sep 17 00:00:00 2001
From: alirezamoshtaghi <alireza.moshtaghi at gmail.com>
Date: Tue, 5 Mar 2024 00:04:52 -0800
Subject: [PATCH 3/3] dont test designator on Windows
---
clang-tools-extra/clangd/test/designator_init.test | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/clangd/test/designator_init.test b/clang-tools-extra/clangd/test/designator_init.test
index 739f2bfab54bcf..4009945ed81fd4 100644
--- a/clang-tools-extra/clangd/test/designator_init.test
+++ b/clang-tools-extra/clangd/test/designator_init.test
@@ -1,7 +1,7 @@
//# 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
-
+//# UNSUPPORTED: system-windows
typedef struct S {
unsigned char id;
union {
More information about the cfe-commits
mailing list