Skip to content
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

[clang] Support __is_trivially_copyable(int()&)==false #81298

Merged
merged 10 commits into from
Mar 5, 2024

Conversation

AMP999
Copy link
Contributor

@AMP999 AMP999 commented Feb 9, 2024

IMHO it would be productive to make a similar change for typeid, in ParseCXXTypeid, in order to improve Clang's error message for https://godbolt.org/z/oKKWxeYra
But that might be better done by adding a new DeclaratorContext specifically for TypeidArg, instead of pretending that the argument to typeid is a template argument, because I don't know what else that change might affect.

Fixes #77585

IMHO it would be productive to make a similar change for `typeid`,
in `ParseCXXTypeid`, in order to improve Clang's error message for
https://godbolt.org/z/oKKWxeYra
But that might be better done by adding a new DeclaratorContext
specifically for TypeidArg, instead of pretending that the argument
to `typeid` is a template argument, because I don't know what else
that change might affect.

Fixes llvm#77585
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Feb 9, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Feb 9, 2024

@llvm/pr-subscribers-clang

Author: Amirreza Ashouri (AMP999)

Changes

IMHO it would be productive to make a similar change for typeid, in ParseCXXTypeid, in order to improve Clang's error message for https://godbolt.org/z/oKKWxeYra
But that might be better done by adding a new DeclaratorContext specifically for TypeidArg, instead of pretending that the argument to typeid is a template argument, because I don't know what else that change might affect.

Fixes #77585


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

1 Files Affected:

  • (modified) clang/lib/Parse/ParseExprCXX.cpp (+4-2)
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index fd262ff31e661a..746a8b2286ac4c 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -3899,7 +3899,9 @@ ExprResult Parser::ParseTypeTrait() {
   SmallVector<ParsedType, 2> Args;
   do {
     // Parse the next type.
-    TypeResult Ty = ParseTypeName();
+    TypeResult Ty = ParseTypeName(nullptr, getLangOpts().CPlusPlus
+                                               ? DeclaratorContext::TemplateArg
+                                               : DeclaratorContext::TypeName);
     if (Ty.isInvalid()) {
       Parens.skipToEnd();
       return ExprError();
@@ -3941,7 +3943,7 @@ ExprResult Parser::ParseArrayTypeTrait() {
   if (T.expectAndConsume())
     return ExprError();
 
-  TypeResult Ty = ParseTypeName();
+  TypeResult Ty = ParseTypeName(nullptr, DeclaratorContext::TemplateArg);
   if (Ty.isInvalid()) {
     SkipUntil(tok::comma, StopAtSemi);
     SkipUntil(tok::r_paren, StopAtSemi);

Copy link
Collaborator

@erichkeane erichkeane left a comment

Choose a reason for hiding this comment

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

This would need a release note + I think it needs better testing. @AaronBallman might wish to take a look as well, this is his code ownership.

@@ -57,7 +57,7 @@ UNION(char[2], short) u2 = { .one = { 'a', 'b' } }; // ext-warning 3 {{'_Static_
typedef UNION(char, short) U3; // expected-error {{static assertion failed due to requirement 'sizeof(char) == sizeof(short)': type size mismatch}} \
// expected-note{{evaluates to '1 == 2'}} \
// ext-warning 3 {{'_Static_assert' is a C11 extension}}
typedef UNION(float, 0.5f) U4; // expected-error {{expected a type}} \
typedef UNION(float, 0.5f) U4; // expected-error-re {{{{type name requires a specifier or qualifier|expected a type}}}} \
Copy link
Collaborator

Choose a reason for hiding this comment

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

This test doesn't seem right... why is there an 'or' here?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think there's an 'or' because the RUN lines run this in both C and C++ mode, so you get different diagnostics. A better way to express that is with a different -verify prefix on the RUN lines so that you can do something like cpp-error {{blah}} and c-error {{blah}} to make it more clear what's happening.

@@ -3899,7 +3899,9 @@ ExprResult Parser::ParseTypeTrait() {
SmallVector<ParsedType, 2> Args;
do {
// Parse the next type.
TypeResult Ty = ParseTypeName();
TypeResult Ty = ParseTypeName(nullptr, getLangOpts().CPlusPlus
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
TypeResult Ty = ParseTypeName(nullptr, getLangOpts().CPlusPlus
TypeResult Ty = ParseTypeName(/*SourceRange=*/nullptr, getLangOpts().CPlusPlus

Copy link
Contributor

@cor3ntin cor3ntin left a comment

Choose a reason for hiding this comment

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

This is going to need additional tests (ie a test for __is_trivially_copyable(int()&) would be a good start!)

@@ -3941,7 +3943,7 @@ ExprResult Parser::ParseArrayTypeTrait() {
if (T.expectAndConsume())
return ExprError();

TypeResult Ty = ParseTypeName();
TypeResult Ty = ParseTypeName(nullptr, DeclaratorContext::TemplateArg);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
TypeResult Ty = ParseTypeName(nullptr, DeclaratorContext::TemplateArg);
TypeResult Ty = ParseTypeName(/*SourceRange=*/nullptr, DeclaratorContext::TemplateArg);

@AMP999
Copy link
Contributor Author

AMP999 commented Mar 4, 2024

@cor3ntin I've reflected your suggestions in the code. Could you help me to land this PR, if it looks good to you?

Copy link
Contributor

@cor3ntin cor3ntin left a comment

Choose a reason for hiding this comment

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

LGTM

@cor3ntin cor3ntin merged commit 690bf64 into llvm:main Mar 5, 2024
5 checks passed
AMP999 added a commit to AMP999/llvm-project that referenced this pull request Mar 5, 2024
…for abominable types

With the llvm#81298 being approved, as soon as it gets merged into the `main` branch,
we can completely remove the `has_unique_object_representations` struct and use the builtin instead.
@AMP999 AMP999 deleted the pr8-fix-issue-77585 branch March 16, 2024 22:19
@fahadnayyar
Copy link
Contributor

Hey folks,

Because of this change the error message for certain type traits changed.
For example:

void f(void) {
  __has_nothrow_copy();
}

Earlier the error message was: expected a type
New error message is: type name requires a specifier or qualifier

Ref: https://godbolt.org/z/d4884bYz3

I personally feel the previous error made more sense for this case as the type name is missing in the type trait call. If the type name is present but the qualifier or specifier are not present then only the new message makes sense.

What do you think, is it a regression or correct behaviour?
@AMP999 @cor3ntin @AaronBallman

@AaronBallman
Copy link
Collaborator

I think the former diagnostic is more clear. It seems the issue is around here:

if (isTypeSpecifier(DSC) && !DS.hasTypeSpecifier()) {

We changed the DeclSpecContext so we hit the else if rather than the if because of isTypeSpecifier().

@fahadnayyar
Copy link
Contributor

@AaronBallman precisely!
DSC now is : DSC_template_arg
DSC in earlier clang was : DSC_type_specifier

@AMP999 do you have thoughts about how we can fix this issue?

@fahadnayyar
Copy link
Contributor

Filed this issue: #86997

@AMP999
Copy link
Contributor Author

AMP999 commented Mar 29, 2024

I don't know, but it seems to me that ideally the DSC here would be DSC_template_type_arg, not just DSC_template_arg. Is there a way to make that happen?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Builtin type traits can't handle abominable function types as arguments
6 participants