Skip to content

[Clang][Sema] Fix crash when type used in return statement contains errors #79788

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
Jan 29, 2024

Conversation

shafik
Copy link
Collaborator

@shafik shafik commented Jan 29, 2024

In Sema in BuildReturnStmt(...) when we try to determine is the type is move eligible or copy elidable we don't currently check of the init of the VarDecl contain errors or not. This can lead to a crash since we may send a type that is not complete into getTypeInfo(...) which does not allow this.

This fixes: #63244
#79745

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jan 29, 2024
@llvmbot
Copy link
Member

llvmbot commented Jan 29, 2024

@llvm/pr-subscribers-clang

Author: Shafik Yaghmour (shafik)

Changes

In Sema in BuildReturnStmt(...) when we try to determine is the type is move eligable or copy elidable we don't currently check of the init of the VarDecl contain errors or not. This can lead to a crash since we may send a type that is not complete into getTypeInfo(...) which does not allow this.

This fixes: #63244
#79745


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

2 Files Affected:

  • (modified) clang/lib/Sema/SemaStmt.cpp (+2)
  • (modified) clang/test/SemaCXX/deduced-return-type-cxx14.cpp (+9)
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 9e7c8c7e4e8c12..5d5a29b825ae7d 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3391,6 +3391,8 @@ Sema::NamedReturnInfo Sema::getNamedReturnInfo(Expr *&E,
   const auto *VD = dyn_cast<VarDecl>(DR->getDecl());
   if (!VD)
     return NamedReturnInfo();
+  if (VD->getInit() && VD->getInit()->containsErrors())
+    return NamedReturnInfo();
   NamedReturnInfo Res = getNamedReturnInfo(VD);
   if (Res.Candidate && !E->isXValue() &&
       (Mode == SimplerImplicitMoveMode::ForceOn ||
diff --git a/clang/test/SemaCXX/deduced-return-type-cxx14.cpp b/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
index c0d43911b8c717..415bbbf1a0bc50 100644
--- a/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
+++ b/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
@@ -724,3 +724,12 @@ struct DeducedTargetTypeOfConversionFunction {
   // since-cxx20-error@-1 {{'decltype(auto)' not allowed in declaration of conversion function template}}
 #endif
 };
+
+namespace GH79745 {
+template <typename = int> struct a; // expected-note {{template is declared here}}
+auto f() {
+  a c; // cxx20_23-error {{implicit instantiation of undefined template}} \
+       // cxx14-error {{use of class template 'a' requires template arguments}}
+  return c;
+}
+}

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.

Missing changelog, otherwise LGTM

@Fznamznon
Copy link
Contributor

Fznamznon commented Jan 29, 2024

NIT: eligable -> eligible in the description.

@shafik shafik force-pushed the undefinedTemplateCrashFixContainsErrors branch from 82d2561 to dde16b4 Compare January 29, 2024 16:23
…rrors

In Sema in `BuildReturnStmt(...)` when we try to determine is the type is move
eligable or copy elidable we don't currently check of the init of the `VarDecl`
contain errors or not. This can lead to a crash since we may send a type that
is not complete into `getTypeInfo(...)` which does not allow this.

This fixes: llvm#63244
llvm#79745
@shafik shafik force-pushed the undefinedTemplateCrashFixContainsErrors branch from dde16b4 to f7f1007 Compare January 29, 2024 17:14
@shafik shafik merged commit 7b0396f into llvm:main Jan 29, 2024
@shafik shafik deleted the undefinedTemplateCrashFixContainsErrors branch January 29, 2024 18:08
@ahatanak
Copy link
Collaborator

ahatanak commented Aug 21, 2024

I think this change can confuse users in some cases.

class Error {
public:
  Error() = default;
  Error(Error &&);
  Error &operator=(Error &&);
  explicit operator bool() const;
};

Error getError();

Error foo() {
  if (Error e = getError(1)) { // error: no matching function for call to 'getError'
    return e; // call to implicitly-deleted copy constructor of 'Error'
  }
  return Error();
}

When the code above is compiled, clang complains that the implicitly-deleted copy constructor of 'Error' is called. This makes users wonder why return e isn't eligible for copy elision.

I wonder whether it would be better to check that VD's type is incomplete rather than calling containsErrors.

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.

Clang frontend C++ crash on invalid code in template-parameter-list
5 participants