https://github.com/ChenMiaoi created 
https://github.com/llvm/llvm-project/pull/229612

The macro exemption checks the start location of the entire expression, so 
parentheses written at the use site cause null pointer macros such as `NULL` to 
be diagnosed. Ignore parentheses when checking the macro origin.

For example:

```c
int *a = (NULL);
```

With `-Wimplicit-void-ptr-cast`, this previously produced:

```txt
test.c:1:6: warning: implicit conversion when initializing 'int *' with an 
expression of type 'void *' is not permitted in C++ [-Wimplicit-void-ptr-cast]
    1 | int *a = (NULL);
      |      ^   ~~~~~~
1 warning generated.
```

After the fix, no warning is emitted.

Fixes #171874

>From 29c840793da85433a0274be20b8b75c03ba6d24b Mon Sep 17 00:00:00 2001
From: Chen Miao <[email protected]>
Date: Wed, 7 Oct 2026 07:40:52 +0800
Subject: [PATCH] [clang][Sema] Fix -Wimplicit-void-ptr-cast for parenthesized
 null macros

The macro exemption checks the start location of the entire expression,
so parentheses written at the use site cause null pointer macros such as
`NULL` to be diagnosed. Ignore parentheses when checking the macro origin.

For example:

```c
int *a = (NULL);
```

With `-Wimplicit-void-ptr-cast`, this previously produced:

```txt
test.c:1:6: warning: implicit conversion when initializing 'int *' with an 
expression of type 'void *' is not permitted in C++ [-Wimplicit-void-ptr-cast]
    1 | int *a = (NULL);
      |      ^   ~~~~~~
1 warning generated.
```

After the fix, no warning is emitted.

Fixes #171874
---
 clang/lib/Sema/SemaExpr.cpp              |  5 +++--
 clang/test/Sema/implicit-void-ptr-cast.c | 18 ++++++++++++++++++
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 9b3384cdbdac8c..a51889ed9b3aae 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -10427,9 +10427,10 @@ AssignConvertType 
Sema::CheckSingleAssignmentConstraints(QualType LHSType,
       // a macro expansion because the use of a macro may indicate different
       // code between C and C++. Consider: char *s = NULL; where NULL is
       // defined as (void *)0 in C (which would be invalid in C++), but 0 in
-      // C++, which is valid in C++.
+      // C++, which is valid in C++. Ignore parentheses around the macro when
+      // checking where the expression originates.
       if (Kind != CK_NoOp && !getLangOpts().CPlusPlus &&
-          !RHS.get()->getBeginLoc().isMacroID()) {
+          !RHS.get()->IgnoreParens()->getBeginLoc().isMacroID()) {
         QualType CanRHS =
             RHS.get()->getType().getCanonicalType().getUnqualifiedType();
         QualType CanLHS = LHSType.getCanonicalType().getUnqualifiedType();
diff --git a/clang/test/Sema/implicit-void-ptr-cast.c 
b/clang/test/Sema/implicit-void-ptr-cast.c
index 037feaa137289a..23faf2c7b7e6df 100644
--- a/clang/test/Sema/implicit-void-ptr-cast.c
+++ b/clang/test/Sema/implicit-void-ptr-cast.c
@@ -83,6 +83,24 @@ void more(void) {
                                         cxx-error {{assigning to 'char *' from 
incompatible type 'void *'}}
 }
 
+int *gh171874(void) {
+  // Parentheses around a null pointer macro must not defeat the macro
+  // expansion exemption, regardless of the assignment action.
+  int *ptr1 = (NULL);
+  ptr1 = ((NULL));
+  func((NULL));
+
+  // Keep diagnosing explicit void pointer casts and non-null pointer macros.
+  #define ZERO 0
+  int *ptr2 = ((void *)ZERO); // c-warning {{implicit conversion when 
initializing 'int *' with an expression of type 'void *' is not permitted in 
C++}} \
+                               cxx-error {{cannot initialize a variable of 
type 'int *' with an rvalue of type 'void *'}}
+  #undef ZERO
+  int *ptr3 = (SOMETHING_THAT_IS_NOT_NULL); // c-warning {{implicit conversion 
when initializing 'int *' with an expression of type 'void *' is not permitted 
in C++}} \
+                                            cxx-error {{cannot initialize a 
variable of type 'int *' with an rvalue of type 'void *'}}
+
+  return (NULL);
+}
+
 void gh154157(void) {
   #define ATOMIC_VAR_INIT(value) (value)
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to