[clang] [C] Add (new) -Wimplicit-void-ptr-cast to -Wc++-compat (PR #136855)
AaronBallman wrote:
> I think the conversion is dropped in `Sema::CheckAssignmentConstraints`. It
> isn't assigning `CK_NonAtomicToAtomic` to `Kind` because `result` is
> `AssignConvertType::CompatibleVoidPtrToNonVoidPtr`, not
> `AssignConvertType::Compatible`.
>
> ```
> // If we have an atomic type, try a non-atomic assignment, then just add an
> // atomic qualification step.
> if (const AtomicType *AtomicTy = dyn_cast(LHSType)) {
> AssignConvertType result =
> CheckAssignmentConstraints(AtomicTy->getValueType(), RHS, Kind);
> if (result != AssignConvertType::Compatible)
> return result;
> ```
Thank you for the investigation, that's definitely it!
https://github.com/llvm/llvm-project/pull/136855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C] Add (new) -Wimplicit-void-ptr-cast to -Wc++-compat (PR #136855)
ziqingluo-90 wrote: > I think it's worth filing an issue over. I will file an issue. I did bisect and verified that this commit is causing the issue. It is also a mystery to me how this commit could affect AST shapes. https://github.com/llvm/llvm-project/pull/136855 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C] Add (new) -Wimplicit-void-ptr-cast to -Wc++-compat (PR #136855)
AaronBallman wrote: > Hi @AaronBallman I noticed that this commit makes a difference on the example > below. > > ``` > #include > typedef const struct T * T_Ref; > static T_Ref _Atomic x = ATOMIC_VAR_INIT((void*)NULL); > ``` > > After this commit, the AST of the global variable declaration changes---a > level of `-ImplicitCastExpr '_Atomic(CFStringRef)' ` is > removed, resulting in a new `error: initializer element is not a compile-time > constant`. (https://godbolt.org/z/aK8E9o47E) That looks like a bug to me, though `ATOMIC_VAR_INIT` was deprecated in C17 and removed in C23 because it isn't a necessary API for initialization. I think it's worth filing an issue over. Did you bisect it to this commit or was this a guess at the cause? I'm not certain I see how we could drop the atomic conversion from these changes (but the code is dense enough that it may be easy to miss). https://github.com/llvm/llvm-project/pull/136855 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C] Add (new) -Wimplicit-void-ptr-cast to -Wc++-compat (PR #136855)
ziqingluo-90 wrote: Hi @AaronBallman I noticed that this commit makes a difference on the example below. ``` #include typedef const struct T * T_Ref; static T_Ref _Atomic x = ATOMIC_VAR_INIT((void*)NULL); ``` After this commit, the AST of the global variable declaration changes---a level of `-ImplicitCastExpr '_Atomic(CFStringRef)' ` is removed, resulting in a new `error: initializer element is not a compile-time constant`. (https://godbolt.org/z/aK8E9o47E) https://github.com/llvm/llvm-project/pull/136855 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C] Add (new) -Wimplicit-void-ptr-cast to -Wc++-compat (PR #136855)
earnol wrote: Could you please take a look into the issue https://github.com/llvm/llvm-project/issues/138145 i created and provide an input from your side if possible. https://github.com/llvm/llvm-project/pull/136855 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C] Add (new) -Wimplicit-void-ptr-cast to -Wc++-compat (PR #136855)
https://github.com/AaronBallman closed https://github.com/llvm/llvm-project/pull/136855 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C] Add (new) -Wimplicit-void-ptr-cast to -Wc++-compat (PR #136855)
https://github.com/AaronBallman updated
https://github.com/llvm/llvm-project/pull/136855
>From 73a0a93e22976fd8ffdd5df70c459b648b7dd06d Mon Sep 17 00:00:00 2001
From: Aaron Ballman
Date: Wed, 23 Apr 2025 07:15:42 -0400
Subject: [PATCH 1/3] Diagnose implicit void * casts under -Wc++-compat
---
.../include/clang/Basic/DiagnosticSemaKinds.td | 3 +++
clang/include/clang/Sema/Sema.h | 17 +
clang/lib/Sema/SemaDeclAttr.cpp | 4 ++--
clang/lib/Sema/SemaExpr.cpp | 14 +++---
clang/lib/Sema/SemaInit.cpp | 7 +++
clang/lib/Sema/SemaObjC.cpp | 4 ++--
clang/lib/Sema/SemaObjCProperty.cpp | 11 ++-
clang/lib/Sema/SemaOverload.cpp | 1 +
8 files changed, 45 insertions(+), 16 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 45b6e1dc29980..84dc0a7206e63 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8682,6 +8682,9 @@ def err_typecheck_missing_return_type_incompatible :
Error<
"return type must match previous return type}0,1 when %select{block "
"literal|lambda expression}2 has unspecified explicit return type">;
+def warn_compatible_implicit_pointer_conv : Warning<
+ "implicit conversion from %diff{$ to $|type to incompatible type}0,1 is not "
+ "permitted in C++">, InGroup, DefaultIgnore;
def note_incomplete_class_and_qualified_id : Note<
"conformance of forward class %0 to protocol %1 cannot be confirmed">;
def warn_incompatible_qualified_id : Warning<
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 96d81e618494a..0c77c5b5ca30a 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -7786,6 +7786,11 @@ class Sema final : public SemaBase {
/// Compatible - the types are compatible according to the standard.
Compatible,
+/// CompatibleVoidPtrToNonVoidPtr - The types are compatible in C because
+/// a void * can implicitly convert to another pointer type, which we
+/// differentiate for better diagnostic behavior.
+CompatibleVoidPtrToNonVoidPtr,
+
/// PointerToInt - The assignment converts a pointer to an int, which we
/// accept as an extension.
PointerToInt,
@@ -7866,6 +7871,18 @@ class Sema final : public SemaBase {
Incompatible
};
+ bool IsAssignConvertCompatible(AssignConvertType ConvTy) {
+switch (ConvTy) {
+default:
+ return false;
+case Compatible:
+case CompatiblePointerDiscardsQualifiers:
+case CompatibleVoidPtrToNonVoidPtr:
+ return true;
+}
+llvm_unreachable("impossible");
+ }
+
/// DiagnoseAssignmentResult - Emit a diagnostic, if required, for the
/// assignment conversion type specified by ConvTy. This returns true if the
/// conversion was invalid or false if the conversion was accepted.
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 0cadbff13bdbf..642a62765d0d9 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3589,8 +3589,8 @@ static void handleCleanupAttr(Sema &S, Decl *D, const
ParsedAttr &AL) {
// If this ever proves to be a problem it should be easy to fix.
QualType Ty = S.Context.getPointerType(cast(D)->getType());
QualType ParamTy = FD->getParamDecl(0)->getType();
- if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
- ParamTy, Ty) != Sema::Compatible) {
+ if (!S.IsAssignConvertCompatible(S.CheckAssignmentConstraints(
+ FD->getParamDecl(0)->getLocation(), ParamTy, Ty))) {
S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type)
<< NI.getName() << ParamTy << Ty;
return;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 01a021443c94f..8d862fd179823 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -9062,8 +9062,12 @@ checkPointerTypesForAssignment(Sema &S, QualType
LHSType, QualType RHSType,
}
if (rhptee->isVoidType()) {
+// In C, void * to another pointer type is compatible, but we want to note
+// that there will be an implicit conversion happening here.
if (lhptee->isIncompleteOrObjectType())
- return ConvTy;
+ return ConvTy == Sema::Compatible && !S.getLangOpts().CPlusPlus
+ ? Sema::CompatibleVoidPtrToNonVoidPtr
+ : ConvTy;
// As an extension, we allow cast to/from void* to function pointer.
assert(lhptee->isFunctionType());
@@ -9098,7 +9102,7 @@ checkPointerTypesForAssignment(Sema &S, QualType LHSType,
QualType RHSType,
// Types are compatible ignoring the sign. Qualifier incompatibility
// takes priority over sign incompatibility because the sign
// warning can be disabl
[clang] [C] Add (new) -Wimplicit-void-ptr-cast to -Wc++-compat (PR #136855)
https://github.com/erichkeane approved this pull request. https://github.com/llvm/llvm-project/pull/136855 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C] Add (new) -Wimplicit-void-ptr-cast to -Wc++-compat (PR #136855)
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wimplicit-void-ptr-cast %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wc++-compat %s
+// RUN: %clang_cc1 -fsyntax-only -verify=good %s
+// RUN: %clang_cc1 -fsyntax-only -verify=good -Wc++-compat
-Wno-implicit-void-ptr-cast %s
+// good-no-diagnostics
+
+typedef __typeof__(sizeof(int)) size_t;
+extern void *malloc(size_t);
+
+void func(int *); // expected-note {{passing argument to parameter here}}
erichkeane wrote:
This is the perfect time to use bookmarks.
https://github.com/llvm/llvm-project/pull/136855
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
