MitalAshok updated this revision to Diff 547311.
MitalAshok added a comment.
No longer warn on printf("%p", nullptr)
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D156054/new/
https://reviews.llvm.org/D156054
Files:
clang/docs/ReleaseNotes.rst
clang/lib/AST/FormatString.cpp
clang/lib/Sema/SemaExpr.cpp
clang/test/CXX/drs/dr7xx.cpp
clang/test/CodeGen/xcore-abi.c
clang/test/Sema/format-strings-pedantic.c
clang/test/SemaCXX/varargs.cpp
clang/www/cxx_dr_status.html
Index: clang/www/cxx_dr_status.html
===================================================================
--- clang/www/cxx_dr_status.html
+++ clang/www/cxx_dr_status.html
@@ -4373,7 +4373,7 @@
<td><a href="https://cplusplus.github.io/CWG/issues/722.html">722</a></td>
<td>CD2</td>
<td>Can <TT>nullptr</TT> be passed to an ellipsis?</td>
- <td class="none" align="center">Unknown</td>
+ <td class="unreleased" align="center">Clang 18</td>
</tr>
<tr id="726">
<td><a href="https://cplusplus.github.io/CWG/issues/726.html">726</a></td>
Index: clang/test/SemaCXX/varargs.cpp
===================================================================
--- clang/test/SemaCXX/varargs.cpp
+++ clang/test/SemaCXX/varargs.cpp
@@ -55,6 +55,16 @@
(void)__builtin_va_arg(ap, unsigned int);
(void)__builtin_va_arg(ap, bool); // expected-warning {{second argument to 'va_arg' is of promotable type 'bool'; this va_arg has undefined behavior because arguments will be promoted to 'int'}}
+
+ (void)__builtin_va_arg(ap, float); // expected-warning {{second argument to 'va_arg' is of promotable type 'float'; this va_arg has undefined behavior because arguments will be promoted to 'double'}}
+ (void)__builtin_va_arg(ap, __fp16); // expected-warning {{second argument to 'va_arg' is of promotable type '__fp16'; this va_arg has undefined behavior because arguments will be promoted to 'double'}}
+
+#if __cplusplus >= 201103L
+ (void)__builtin_va_arg(ap, decltype(nullptr)); // expected-warning {{second argument to 'va_arg' is of promotable type 'decltype(nullptr)' (aka 'std::nullptr_t'); this va_arg has undefined behavior because arguments will be promoted to 'void *'}}
+#endif
+
+ (void)__builtin_va_arg(ap, int[3]); // expected-warning {{second argument to 'va_arg' is of promotable type 'int[3]'; this va_arg has undefined behavior because arguments will be promoted to 'int *'}}
+ (void)__builtin_va_arg(ap, const int[3]); // expected-warning {{second argument to 'va_arg' is of promotable type 'const int[3]'; this va_arg has undefined behavior because arguments will be promoted to 'const int *'}}
}
#if __cplusplus >= 201103L
Index: clang/test/Sema/format-strings-pedantic.c
===================================================================
--- clang/test/Sema/format-strings-pedantic.c
+++ clang/test/Sema/format-strings-pedantic.c
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-format -Wformat-pedantic %s
// RUN: %clang_cc1 -xobjective-c -fblocks -fsyntax-only -verify -Wno-format -Wformat-pedantic %s
// RUN: %clang_cc1 -xc++ -fsyntax-only -verify -Wno-format -Wformat-pedantic %s
+// RUN: %clang_cc1 -std=c2x -fsyntax-only -verify -Wno-format -Wformat-pedantic %s
__attribute__((format(printf, 1, 2)))
int printf(const char *restrict, ...);
@@ -14,7 +15,7 @@
printf("%p", (id)0); // expected-warning {{format specifies type 'void *' but the argument has type 'id'}}
#endif
-#ifdef __cplusplus
- printf("%p", nullptr); // expected-warning {{format specifies type 'void *' but the argument has type 'std::nullptr_t'}}
+#if !__is_identifier(nullptr)
+ printf("%p", nullptr);
#endif
}
Index: clang/test/CodeGen/xcore-abi.c
===================================================================
--- clang/test/CodeGen/xcore-abi.c
+++ clang/test/CodeGen/xcore-abi.c
@@ -76,7 +76,8 @@
// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[V5]], ptr align 4 [[P]], i32 20, i1 false)
// CHECK: call void @f(ptr noundef [[V5]])
- int* v6 = va_arg (ap, int[4]); // an unusual aggregate type
+ // an unusual aggregate type
+ int* v6 = va_arg (ap, int[4]); // expected-warning{{second argument to 'va_arg' is of promotable type 'int[4]'}}
f(v6);
// CHECK: [[I:%[a-z0-9]+]] = load ptr, ptr [[AP]]
// CHECK: [[P:%[a-z0-9]+]] = load ptr, ptr [[I]]
Index: clang/test/CXX/drs/dr7xx.cpp
===================================================================
--- clang/test/CXX/drs/dr7xx.cpp
+++ clang/test/CXX/drs/dr7xx.cpp
@@ -53,6 +53,15 @@
#endif
}
+namespace dr722 { // dr722: 18
+#if __cplusplus >= 201103L
+ int x = __builtin_printf("%p", nullptr);
+ void f(__builtin_va_list args) {
+ __builtin_va_arg(args, decltype(nullptr)); // expected-warning {{second argument to 'va_arg' is of promotable type 'decltype(nullptr)' (aka 'std::nullptr_t'); this va_arg has undefined behavior because arguments will be promoted to 'void *'}}
+ }
+#endif
+}
+
namespace dr727 { // dr727: partial
struct A {
template<typename T> struct C; // expected-note 6{{here}}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -936,9 +936,9 @@
// enumeration, pointer, pointer to member, or class type, the program
// is ill-formed.
//
- // Since we've already performed array-to-pointer and function-to-pointer
- // decay, the only such type in C++ is cv void. This also handles
- // initializer lists as variadic arguments.
+ // Since we've already performed null pointer conversion, array-to-pointer
+ // decay and function-to-pointer decay, the only such type in C++ is cv
+ // void. This also handles initializer lists as variadic arguments.
if (Ty->isVoidType())
return VAK_Invalid;
@@ -1059,6 +1059,18 @@
E = ExprRes.get();
+ // C2x 6.5.2.2p6:
+ // The integer promotions are performed on each trailing argument, and
+ // trailing arguments that have type float are promoted to double. These are
+ // called the default argument promotions. No other conversions are
+ // performed implicitly.
+
+ // C++ [expr.call]p7, per DR722:
+ // An argument that has (possibly cv-qualified) type std::nullptr_t is
+ // converted to void* ([conv.ptr]).
+ if (E->getType()->isNullPtrType() && getLangOpts().CPlusPlus)
+ E = ImpCastExprToType(E, Context.VoidPtrTy, CK_NullToPointer).get();
+
// Diagnostics regarding non-POD argument types are
// emitted along with format string checking in Sema::CheckFunctionCall().
if (isValidVarArgType(E->getType()) == VAK_Undefined) {
@@ -17302,8 +17314,13 @@
PromoteType = QualType();
}
}
- if (TInfo->getType()->isSpecificBuiltinType(BuiltinType::Float))
+ if (TInfo->getType()->isSpecificBuiltinType(BuiltinType::Float) ||
+ TInfo->getType()->isSpecificBuiltinType(BuiltinType::Half))
PromoteType = Context.DoubleTy;
+ if (TInfo->getType()->isNullPtrType() && getLangOpts().CPlusPlus)
+ PromoteType = Context.VoidPtrTy;
+ if (TInfo->getType()->isArrayType())
+ PromoteType = Context.getArrayDecayedType(TInfo->getType());
if (!PromoteType.isNull())
DiagRuntimeBehavior(TInfo->getTypeLoc().getBeginLoc(), E,
PDiag(diag::warn_second_parameter_to_va_arg_never_compatible)
Index: clang/lib/AST/FormatString.cpp
===================================================================
--- clang/lib/AST/FormatString.cpp
+++ clang/lib/AST/FormatString.cpp
@@ -531,6 +531,9 @@
case CPointerTy:
if (argTy->isVoidPointerType()) {
return Match;
+ } else if (argTy->isNullPtrType()) {
+ // In C, nullptr matches void*. In C++, nullptr gets promoted to void*.
+ return C.getLangOpts().C2x ? Match : MatchPromotion;
} if (argTy->isPointerType() || argTy->isObjCObjectPointerType() ||
argTy->isBlockPointerType() || argTy->isNullPtrType()) {
return NoMatchPedantic;
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -68,6 +68,8 @@
Resolutions to C++ Defect Reports
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+- Implemented `DR722 <https://wg21.link/CWG722>`_ which promotes ``nullptr`` to ``void*``
+ when passed to a C-style variadic function.
C Language Changes
------------------
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits