llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Tony Guillot (to268)

<details>
<summary>Changes</summary>

When using the sentinel attribute on a variadic function with an explicit 
object parameter, the missing sentinel attribute diagnostic takes into account 
the explicit object parameter as an argument. It was diagnosing `missing 
sentinel in function call` instead of `not enough variable arguments in '%0' 
declaration to fit a sentinel`, compared to other similar variadic functions.

Fixes #<!-- -->200007

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


4 Files Affected:

- (modified) clang/docs/ReleaseNotes.md (+3) 
- (modified) clang/lib/Sema/SemaExpr.cpp (+6-1) 
- (modified) clang/test/Sema/attr-sentinel.c (+7-7) 
- (modified) clang/test/SemaCXX/attr-sentinel.cpp (+87-1) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 4e3ea3b91d20f..3ed55f2977f78 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -736,6 +736,9 @@ latest release, please see the [Clang Web 
Site](https://clang.llvm.org) or the
 
 - Added a clearer diagnostic for uninitialized decomposition declarations. 
(#GH90107)
 
+- Fixed missing sentinel attribute diagnostic discrepancy with explicit object
+  parameters in variadic functions. (#GH200007)
+
 ### Improvements to Clang's time-trace
 
 ### Improvements to Coverage Mapping
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 4e9c0eccbe43e..5d842ef6e3cfa 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -467,9 +467,14 @@ void Sema::DiagnoseSentinelCalls(const NamedDecl *D, 
SourceLocation Loc,
   // The number of arguments which should follow the sentinel.
   unsigned NumArgsAfterSentinel = Attr->getSentinel();
 
+  unsigned RequiredNumParams = NumFormalParams + NumArgsAfterSentinel + 1;
+  if (const auto *MD = dyn_cast<CXXMethodDecl>(D))
+    if (MD->isExplicitObjectMemberFunction())
+      RequiredNumParams++;
+
   // If there aren't enough arguments for all the formal parameters,
   // the sentinel, and the args after the sentinel, complain.
-  if (Args.size() < NumFormalParams + NumArgsAfterSentinel + 1) {
+  if (Args.size() < RequiredNumParams) {
     Diag(Loc, diag::warn_not_enough_argument) << D->getDeclName();
     Diag(D->getLocation(), diag::note_sentinel_here) << int(CalleeKind);
     return;
diff --git a/clang/test/Sema/attr-sentinel.c b/clang/test/Sema/attr-sentinel.c
index 9af11296b07f6..04a9a66ad90f5 100644
--- a/clang/test/Sema/attr-sentinel.c
+++ b/clang/test/Sema/attr-sentinel.c
@@ -2,7 +2,7 @@
 
 #define NULL (void*)0
 
-#define ATTR __attribute__ ((__sentinel__)) 
+#define ATTR __attribute__ ((__sentinel__))
 
 void foo1 (int x, ...) ATTR; // expected-note 3 {{function has been explicitly 
marked sentinel here}}
 void foo5 (int x, ...) __attribute__ ((__sentinel__(1))); // expected-note 
{{function has been explicitly marked sentinel here}}
@@ -36,7 +36,7 @@ void test1(void) {
   // PR11002
   FOOMACRO(1, 2); // expected-warning {{missing sentinel in function call}}
 }
- 
+
 
 
 void (*e) (int arg, const char * format, ...) __attribute__ ((__sentinel__ 
(1,1)));
@@ -44,16 +44,16 @@ void (*e) (int arg, const char * format, ...) __attribute__ 
((__sentinel__ (1,1)
 void test2(void) {
   void (*b) (int arg, const char * format, ...) __attribute__ 
((__sentinel__));  // expected-note {{function has been explicitly marked 
sentinel here}}
   void (*z) (int arg, const char * format, ...) __attribute__ ((__sentinel__ 
(2))); // expected-note {{function has been explicitly marked sentinel here}}
-  
-  
+
+
   void (*y) (int arg, const char * format, ...) __attribute__ ((__sentinel__ 
(5))); // expected-note {{function has been explicitly marked sentinel here}}
-  
+
   b(1, "%s", (void*)0); // OK
   b(1, "%s", 0);  // expected-warning {{missing sentinel in function call}}
   z(1, "%s",4 ,1,0);  // expected-warning {{missing sentinel in function call}}
   z(1, "%s", (void*)0, 1, 0); // OK
-  
+
   y(1, "%s", 1,2,3,4,5,6,7);  // expected-warning {{missing sentinel in 
function call}}
-  
+
   y(1, "%s", (void*)0,3,4,5,6,7); // OK
 }
diff --git a/clang/test/SemaCXX/attr-sentinel.cpp 
b/clang/test/SemaCXX/attr-sentinel.cpp
index 92c6e21444fa3..e11ac16fe6bcf 100644
--- a/clang/test/SemaCXX/attr-sentinel.cpp
+++ b/clang/test/SemaCXX/attr-sentinel.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 -std=c++17 %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx23 -std=c++23 %s
 
 void f(int, ...) __attribute__((sentinel));
 
@@ -21,3 +22,88 @@ void class_test() {
   s2->a(1,2,3); // expected-warning {{missing sentinel in function call}}
   s(1,2,3); // expected-warning {{missing sentinel in function call}}
 }
+
+namespace consistent_diganostic_test {
+struct Ty {
+    void baseline0(int, ...) __attribute__((sentinel));     // #BASELINE0_NOTE
+    void baseline1(int, ...) __attribute__((sentinel(1)));  // #BASELINE1_NOTE
+    void baseline2(int, ...) __attribute__((sentinel(2)));  // #BASELINE2_NOTE
+
+    template<typename T>
+    int&& foo(T&& val, ...) __attribute__((sentinel(1))); // #FOO_NOTE
+
+    template<class Self>
+    int&& bar(this Self&& self, ...) __attribute__((sentinel(1))); // #BAR_NOTE
+    // cxx17-error@-1 {{explicit object parameters are incompatible with C++ 
standards before C++2b}}
+};
+
+void test_baseline0() {
+    auto sty = Ty{};
+
+    sty.baseline0(1);
+    // expected-warning@-1 {{not enough variable arguments in 'baseline0' 
declaration to fit a sentinel}}
+    // expected-note@#BASELINE0_NOTE {{function has been explicitly marked 
sentinel here}}
+
+    sty.baseline0(1, 2);
+    // expected-warning@-1 {{missing sentinel in function call}}
+    // expected-note@#BASELINE0_NOTE {{function has been explicitly marked 
sentinel here}}
+
+    sty.baseline0(1, 2, nullptr);
+}
+
+void test_baseline1() {
+    auto sty = Ty{};
+
+    sty.baseline1(1, 3);
+    // expected-warning@-1 {{not enough variable arguments in 'baseline1' 
declaration to fit a sentinel}}
+    // expected-note@#BASELINE1_NOTE {{function has been explicitly marked 
sentinel here}}
+
+    sty.baseline1(1, 2, 3);
+    // expected-warning@-1 {{missing sentinel in function call}}
+    // expected-note@#BASELINE1_NOTE {{function has been explicitly marked 
sentinel here}}
+
+    sty.baseline1(1, 2, nullptr, 3);
+}
+
+void test_baseline2() {
+    auto sty = Ty{};
+
+    sty.baseline2(1, 2, 3);
+    // expected-warning@-1 {{not enough variable arguments in 'baseline2' 
declaration to fit a sentinel}}
+    // expected-note@#BASELINE2_NOTE {{function has been explicitly marked 
sentinel here}}
+
+    sty.baseline2(1, 2, 3, 4);
+    // expected-warning@-1 {{missing sentinel in function call}}
+    // expected-note@#BASELINE2_NOTE {{function has been explicitly marked 
sentinel here}}
+
+    sty.baseline2(1, 2, nullptr, 3, 4);
+}
+
+void test_foo() {
+    auto sty = Ty{};
+
+    sty.foo(1, 2);
+    // expected-warning@-1 {{not enough variable arguments in 'foo' 
declaration to fit a sentinel}}
+    // expected-note@#FOO_NOTE {{function has been explicitly marked sentinel 
here}}
+
+    sty.foo(1, 2, 3);
+    // expected-warning@-1 {{missing sentinel in function call}}
+    // expected-note@#FOO_NOTE {{function has been explicitly marked sentinel 
here}}
+
+    sty.foo(1, nullptr, 3);
+}
+
+void test_bar() {
+    auto sty = Ty{};
+
+    sty.bar(1, 2);
+    // expected-warning@-1 {{not enough variable arguments in 'bar' 
declaration to fit a sentinel}}
+    // expected-note@#BAR_NOTE {{function has been explicitly marked sentinel 
here}}
+
+    sty.bar(1, 2, 3);
+    // expected-warning@-1 {{missing sentinel in function call}}
+    // expected-note@#BAR_NOTE {{function has been explicitly marked sentinel 
here}}
+
+    sty.bar(1, nullptr, 3);
+}
+} // namespace consistent_diganostic_test

``````````

</details>


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

Reply via email to