From bbc4eea2c26960ced56906d4a2573c8c1d291dc2 Mon Sep 17 00:00:00 2001
From: Jeffrey Yasskin
Date: Thu, 27 Jan 2011 19:17:54 +0000
Subject: [PATCH] Revert r124217 because it didn't catch the actual error case
it was trying to catch:
lock_guard(my_mutex);
declares a variable instead of creating a temporary.
llvm-svn: 124398
---
clang/docs/LanguageExtensions.html | 28 -----------
clang/include/clang/Basic/Attr.td | 5 --
.../clang/Basic/DiagnosticSemaKinds.td | 3 --
clang/include/clang/Sema/AttributeList.h | 1 -
clang/lib/Sema/AttributeList.cpp | 1 -
clang/lib/Sema/SemaDeclAttr.cpp | 20 --------
clang/lib/Sema/SemaExprCXX.cpp | 5 +-
clang/test/SemaCXX/forbid-temporaries.cpp | 50 -------------------
8 files changed, 1 insertion(+), 112 deletions(-)
delete mode 100644 clang/test/SemaCXX/forbid-temporaries.cpp
diff --git a/clang/docs/LanguageExtensions.html b/clang/docs/LanguageExtensions.html
index b2b3f3cde678..30c85ffcbd3f 100644
--- a/clang/docs/LanguageExtensions.html
+++ b/clang/docs/LanguageExtensions.html
@@ -25,7 +25,6 @@ td {
Vectors and Extended Vectors
Messages on deprecated and unavailable attributes
Attributes on enumerators
-Attribute to forbid temporaries of a type
Checks for Standard Language Features
Query for this feature with __has_feature(enumerator_attributes).
-
-Attribute to forbid temporaries of a type
-
-
-Clang provides a forbid_temporaries attribute to forbid
-temporaries of a particular type.
-
-
-class __attribute__((forbid_temporaries)) scoped_lock {
- ...
-};
-
-
-This prevents mistakes like
-
-
-void foo() {
- scoped_lock(my_mutex);
- // Forgot the local variable name, so destructor runs here.
- code_that_needs_lock_held();
- // User expects destructor to run here.
-};
-
-
-Query for this feature with __has_attribute(forbid_temporaries).
-Use -Wno-forbid-temporaries to disable the resulting warning.
-
Checks for Standard Language Features
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 010736112d82..9b0982a29b9f 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -232,11 +232,6 @@ def Final : InheritableAttr {
let Spellings = [];
}
-def ForbidTemporaries : Attr {
- let Spellings = ["forbid_temporaries"];
- let Subjects = [CXXRecord];
-}
-
def Format : InheritableAttr {
let Spellings = ["format"];
let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">,
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index cb87f0d5e6b6..17bbc68afb7d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -861,9 +861,6 @@ def err_temp_copy_deleted : Error<
"of type %1 invokes deleted constructor">;
def err_temp_copy_incomplete : Error<
"copying a temporary object of incomplete type %0">;
-def warn_temporaries_forbidden : Warning<
- "must not create temporaries of type %0">,
- InGroup>;
// C++0x decltype
def err_cannot_determine_declared_type_of_overloaded_function : Error<
diff --git a/clang/include/clang/Sema/AttributeList.h b/clang/include/clang/Sema/AttributeList.h
index 7ed6ffcdaf0b..91389a4d9847 100644
--- a/clang/include/clang/Sema/AttributeList.h
+++ b/clang/include/clang/Sema/AttributeList.h
@@ -104,7 +104,6 @@ public:
AT_dllimport,
AT_ext_vector_type,
AT_fastcall,
- AT_forbid_temporaries,
AT_format,
AT_format_arg,
AT_global,
diff --git a/clang/lib/Sema/AttributeList.cpp b/clang/lib/Sema/AttributeList.cpp
index c3efda9a7a3a..77d962542bfc 100644
--- a/clang/lib/Sema/AttributeList.cpp
+++ b/clang/lib/Sema/AttributeList.cpp
@@ -85,7 +85,6 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
.Case("deprecated", AT_deprecated)
.Case("visibility", AT_visibility)
.Case("destructor", AT_destructor)
- .Case("forbid_temporaries", AT_forbid_temporaries)
.Case("format_arg", AT_format_arg)
.Case("gnu_inline", AT_gnu_inline)
.Case("weak_import", AT_weak_import)
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 21d0f46528a3..474c7cb82f9e 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -885,24 +885,6 @@ static void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
}
-static void HandleForbidTemporariesAttr(Decl *d, const AttributeList &Attr,
- Sema &S) {
- assert(Attr.isInvalid() == false);
-
- if (Attr.getNumArgs() != 0) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
- return;
- }
-
- if (!isa(d)) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << Attr.getName() << 9 /*class*/;
- return;
- }
-
- d->addAttr(::new (S.Context) ForbidTemporariesAttr(Attr.getLoc(), S.Context));
-}
-
static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
if (!isFunctionOrMethod(d) && !isa(d)) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
@@ -2692,8 +2674,6 @@ static void ProcessInheritableDeclAttr(Scope *scope, Decl *D,
case AttributeList::AT_ext_vector_type:
HandleExtVectorTypeAttr(scope, D, Attr, S);
break;
- case AttributeList::AT_forbid_temporaries:
- HandleForbidTemporariesAttr(D, Attr, S); break;
case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break;
case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break;
case AttributeList::AT_global: HandleGlobalAttr (D, Attr, S); break;
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 8581c6f64948..e95bad4d0a69 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -3294,12 +3294,9 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) {
}
}
- CXXRecordDecl *RD = cast(RT->getDecl());
- if (RD->getAttr())
- Diag(E->getExprLoc(), diag::warn_temporaries_forbidden) << E->getType();
-
// That should be enough to guarantee that this type is complete.
// If it has a trivial destructor, we can avoid the extra copy.
+ CXXRecordDecl *RD = cast(RT->getDecl());
if (RD->isInvalidDecl() || RD->hasTrivialDestructor())
return Owned(E);
diff --git a/clang/test/SemaCXX/forbid-temporaries.cpp b/clang/test/SemaCXX/forbid-temporaries.cpp
deleted file mode 100644
index cbe47aed5e28..000000000000
--- a/clang/test/SemaCXX/forbid-temporaries.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-#if !__has_attribute(forbid_temporaries)
-#error "Should support forbid_temporaries attribute"
-#endif
-
-class __attribute__((forbid_temporaries)) NotATemporary {
-};
-
-class __attribute__((forbid_temporaries(1))) ShouldntHaveArguments { // expected-error {{attribute requires 0 argument(s)}}
-};
-
-void bad_function() __attribute__((forbid_temporaries)); // expected-warning {{'forbid_temporaries' attribute only applies to classes}}
-
-int var __attribute__((forbid_temporaries)); // expected-warning {{'forbid_temporaries' attribute only applies to classes}}
-
-void bar(const NotATemporary&);
-
-void foo() {
- NotATemporary this_is_fine;
- bar(NotATemporary()); // expected-warning {{must not create temporaries of type 'NotATemporary'}}
- NotATemporary(); // expected-warning {{must not create temporaries of type 'NotATemporary'}}
-}
-
-
-// Check that the above restrictions work for templates too.
-template
-class __attribute__((forbid_temporaries)) NotATemporaryTpl {
-};
-
-template
-void bar_tpl(const NotATemporaryTpl&);
-
-void tpl_user() {
- NotATemporaryTpl this_is_fine;
- bar_tpl(NotATemporaryTpl()); // expected-warning {{must not create temporaries of type 'NotATemporaryTpl'}}
- NotATemporaryTpl(); // expected-warning {{must not create temporaries of type 'NotATemporaryTpl'}}
-}
-
-
-// Test that a specialization can override the template's default.
-struct TemporariesOk;
-template<> class NotATemporaryTpl {
-};
-
-void specialization_user() {
- NotATemporaryTpl this_is_fine;
- bar_tpl(NotATemporaryTpl());
- NotATemporaryTpl();
-}