Skip to content

[Clang] Implement CWG2518 - static_assert(false) #9200

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 1, 2024

Conversation

compnerd
Copy link
Member

This allows static_assert(false) to not be ill-formed in template definitions.

This change is applied as a DR in all C++ modes.

Of notes, a couple of tests were relying of the eager nature of static_assert

  • test/SemaTemplate/instantiation-dependence.cpp
  • test/SemaTemplate/instantiate-var-template.cpp

I don't know if the changes to static_assert
still allow that sort of tests to be expressed.

Reviewed By: #clang-language-wg, erichkeane, aaron.ballman

Differential Revision: https://reviews.llvm.org/D144285

(cherry picked from commit 00e2098)

This allows `static_assert(false)` to not be ill-formed
in template definitions.

This change is applied as a DR in all C++ modes.

Of notes, a couple of tests were relying of the eager nature
of static_assert

* test/SemaTemplate/instantiation-dependence.cpp
* test/SemaTemplate/instantiate-var-template.cpp

I don't know if the changes to `static_assert`
still allow that sort of tests to be expressed.

Reviewed By: #clang-language-wg, erichkeane, aaron.ballman

Differential Revision: https://reviews.llvm.org/D144285

(cherry picked from commit 00e2098)
@compnerd
Copy link
Member Author

@swift-ci please test

@compnerd compnerd merged commit 4857f75 into swiftlang:stable/20230725 Sep 1, 2024
3 checks passed
@compnerd compnerd deleted the static_assert_false branch September 1, 2024 04:40
@ahatanaka
Copy link

It looks like this commit broke the following clang tests:

  • CXX/drs/dr25xx.cpp
  • SemaCXX/static-assert-cxx26.cpp
  • SemaCXX/static-assert.cpp

@compnerd, could you fix them?

@compnerd
Copy link
Member Author

compnerd commented Sep 4, 2024

@ahatanaka sure - do you have a link to the failure? I'm mostly building on Windows. It seems that there might be local changes to the tests as this was a direct cherry-pick from upstream.

@ahatanaka
Copy link

Unfortunately, this is an internal CI failure, so we can't share the link with you. You can reproduce the failure by checking out this branch and running the tests: https://github.com/swiftlang/llvm-project/tree/stable/20230725.

@ahatanaka
Copy link

It looks like clang fails to compile the code you added when the target C++ standard is old.

error: 'error' diagnostics seen but not expected:
  File clang/test/CXX/drs/dr25xx.cpp Line 88: expected '(' after 'if'
  File clang/test/CXX/drs/dr25xx.cpp Line 89: expected directive cannot follow 'expected-no-diagnostics' directive
  File clang/test/CXX/drs/dr25xx.cpp Line 95: expected directive cannot follow 'expected-no-diagnostics' directive
  File clang/test/CXX/drs/dr25xx.cpp Line 100: expected parameter declarator
  File clang/test/CXX/drs/dr25xx.cpp Line 100: expected ')'
  File clang/test/CXX/drs/dr25xx.cpp Line 100: a type specifier is required for all declarations
  File clang/test/CXX/drs/dr25xx.cpp Line 100: expected directive cannot follow 'expected-no-diagnostics' directive
  File clang/test/CXX/drs/dr25xx.cpp Line 112: expected directive cannot follow 'expected-no-diagnostics' directive
error: 'note' diagnostics seen but not expected:
  File clang/test/CXX/drs/dr25xx.cpp Line 100: to match this '('
9 errors generated.

Note that 00e2098 only tests -std=c++20.

@drodriguez
Copy link

Got the same kind of errors in our own internal CI.

I don't understand why this needs to be cherry-picked, though. This branch is supposed to be branched on 2023-07-23, and the commit was landed in LLVM upstream 2023-02-28. In fact it is part of the branch already in 00e2098.

If one compare the diffs of this PR and 00e2098, probably because cherry-picking this diff overwrites some other commits since the original, instead of reapplying it cleanly.

Can we revert this?

@compnerd
Copy link
Member Author

compnerd commented Sep 6, 2024

The change to clang/lib/Sema/SemaDeclCXX.cpp seems to be missing - the early check does result in a failure of static_assert(false) for an unevaluated template. The diff shows this matching up the behaviour there.

Copy link

@drodriguez drodriguez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be reverted ASAP. I can prepare the PR, but I cannot merge myself, so if someone can do it quicker, please do.

A simple @swift-ci please test in changes of the llvm-project is normally not enough to catch things. I recommend @swift-ci please llvm test but it is normally broken for other causes, so it cannot be used as a barrier for merging.

Comment on lines -17149 to -17156
// If the static_assert passes, only verify that
// the message is grammatically valid without evaluating it.
if (!Failed && AssertMessage && Cond.getBoolValue()) {
std::string Str;
EvaluateStaticAssertMessageAsString(AssertMessage, Str, Context,
/*ErrorOnInvalidMessage=*/false);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bit is added in 47ccfd7 (https://reviews.llvm.org/D154290) on 2023-07-19, after the commit that is being double cherry-picked added the chunk of code below.

Comment on lines -17195 to +17189
Diag(AssertExpr->getBeginLoc(), diag::err_static_assert_failed)
<< !HasMessage << Msg.str() << AssertExpr->getSourceRange();
Diag(StaticAssertLoc, diag::err_static_assert_failed)
<< !AssertMessage << Msg.str() << AssertExpr->getSourceRange();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This two lines are undoing the changes in:

Comment on lines +84 to +117
namespace dr2518 { // dr2518: 17 review

template <class T>
void f(T t) {
if constexpr (sizeof(T) != sizeof(int)) {
static_assert(false, "must be int-sized"); // expected-error {{must be int-size}}
}
}

void g(char c) {
f(0);
f(c); // expected-note {{requested here}}
}

template <typename Ty>
struct S {
static_assert(false); // expected-error {{static assertion failed}}
};

template <>
struct S<int> {};

template <>
struct S<float> {};

int test_specialization() {
S<int> s1;
S<float> s2;
S<double> s3; // expected-note {{in instantiation of template class 'dr2518::S<double>' requested here}}
}

}


Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same namespace exist in line 24 above, but that code includes modifications to the original test that are not part of this repeated section, like the ones introduced in 5ce5e98 which should avoid one of the failures we are experiencing in the tests.

drodriguez added a commit that referenced this pull request Sep 6, 2024
This reverts commit 4857f75, reversing
changes made to fe0f467.

This reverts PR #9200.

The cherry-pick that's being tried in that PR is already part of the
branch (00e2098), and the commit removes code added after the original
commit, and duplicates some testing code, producing errors in several
tests.

See the comments of #9200 for more details.
drodriguez added a commit that referenced this pull request Sep 6, 2024
Revert "Merge pull request #9200 from compnerd/static_assert_false"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants