arphaman created this revision.
arphaman added reviewers: rsmith, rjmccall.
arphaman added a subscriber: cfe-commits.
arphaman set the repository for this revision to rL LLVM.
This patch fixes a crash that happens because of an assertion failure in C mode
only. The assertion failure happens because of a cast to a C++ record decl in
code that assumes (correctly, AFAIK) that overloaded operator handling is used
in C++ mode only.
This patch approaches this problem in the following manner: when clang isn't in
C++ mode, it exits early from the method 'Sema::CreateOverloadedBinOp'. The
operator handling is performed using the 'Sema::CreateBuiltinBinOp' method when
exiting the previously mentioned method. I think that this approach works
because, AFAIK, clang doesn't support operator overloading without
LangOpts.CPlusPlus, so it doesn't need to handle the overloading in the same
way, and redirecting to builtin operator handling deals with the C operators
correctly. I also tried other approaches and strategies but they didn't seem to
work as well as this one.
I'm not familiar with all the intricacies of Sema, and I realize that this
might be the wrong approach for this problem. Please let me know if this a
sound strategy or not.
This bug is a regression since r236337.
Repository:
rL LLVM
https://reviews.llvm.org/D25213
Files:
lib/Sema/SemaOverload.cpp
test/Sema/PR28181.c
Index: test/Sema/PR28181.c
===================================================================
--- /dev/null
+++ test/Sema/PR28181.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct spinlock_t {
+ int lock;
+} audit_skb_queue;
+
+void fn1() {
+ audit_skb_queue = (lock); // expected-error {{use of undeclared identifier
'lock'; did you mean 'long'?}}
+} // expected-error@-1 {{assigning to 'struct
spinlock_t' from incompatible type '<overloaded function type>'}}
+
+void fn2() {
+ audit_skb_queue + (lock); // expected-error {{use of undeclared identifier
'lock'; did you mean 'long'?}}
+} // expected-error@-1 {{reference to overloaded
function could not be resolved; did you mean to call it?}}
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -11804,7 +11804,8 @@
// various built-in candidates, but as DR507 points out, this can lead to
// problems. So we do it this way, which pretty much follows what GCC does.
// Note that we go the traditional code path for compound assignment forms.
- if (Opc == BO_Assign && !Args[0]->getType()->isOverloadableType())
+ if (!LangOpts.CPlusPlus ||
+ (Opc == BO_Assign && !Args[0]->getType()->isOverloadableType()))
return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
// If this is the .* operator, which is not overloadable, just
Index: test/Sema/PR28181.c
===================================================================
--- /dev/null
+++ test/Sema/PR28181.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct spinlock_t {
+ int lock;
+} audit_skb_queue;
+
+void fn1() {
+ audit_skb_queue = (lock); // expected-error {{use of undeclared identifier 'lock'; did you mean 'long'?}}
+} // expected-error@-1 {{assigning to 'struct spinlock_t' from incompatible type '<overloaded function type>'}}
+
+void fn2() {
+ audit_skb_queue + (lock); // expected-error {{use of undeclared identifier 'lock'; did you mean 'long'?}}
+} // expected-error@-1 {{reference to overloaded function could not be resolved; did you mean to call it?}}
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -11804,7 +11804,8 @@
// various built-in candidates, but as DR507 points out, this can lead to
// problems. So we do it this way, which pretty much follows what GCC does.
// Note that we go the traditional code path for compound assignment forms.
- if (Opc == BO_Assign && !Args[0]->getType()->isOverloadableType())
+ if (!LangOpts.CPlusPlus ||
+ (Opc == BO_Assign && !Args[0]->getType()->isOverloadableType()))
return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
// If this is the .* operator, which is not overloadable, just
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits