]> granicus.if.org Git - clang/commitdiff
Revert r124217 because it didn't catch the actual error case it was trying to
authorJeffrey Yasskin <jyasskin@google.com>
Thu, 27 Jan 2011 19:17:54 +0000 (19:17 +0000)
committerJeffrey Yasskin <jyasskin@google.com>
Thu, 27 Jan 2011 19:17:54 +0000 (19:17 +0000)
catch:

  lock_guard(my_mutex);

declares a variable instead of creating a temporary.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124398 91177308-0d34-0410-b5e6-96231b3b80d8

docs/LanguageExtensions.html
include/clang/Basic/Attr.td
include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Sema/AttributeList.h
lib/Sema/AttributeList.cpp
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaExprCXX.cpp
test/SemaCXX/forbid-temporaries.cpp [deleted file]

index b2b3f3cde678de658f58d5f4edf384d5b41011a1..30c85ffcbd3fb1082206050ecdc7efb75e93ccb0 100644 (file)
@@ -25,7 +25,6 @@ td {
 <li><a href="#vectors">Vectors and Extended Vectors</a></li>
 <li><a href="#deprecated">Messages on <tt>deprecated</tt> and <tt>unavailable</tt> attributes</a></li>
 <li><a href="#attributes-on-enumerators">Attributes on enumerators</a></li>
-<li><a href="#forbid-temporaries-attribute">Attribute to forbid temporaries of a type</a></li>
 <li><a href="#checking_language_features">Checks for Standard Language Features</a></li>
   <ul>
   <li><a href="#cxx_exceptions">C++ exceptions</a></li>
@@ -342,33 +341,6 @@ individual enumerators.</p>
 
 <p>Query for this feature with <tt>__has_feature(enumerator_attributes)</tt>.</p>
 
-<!-- ======================================================================= -->
-<h2 id="forbid-temporaries-attribute">Attribute to forbid temporaries of a type</h2>
-<!-- ======================================================================= -->
-
-<p>Clang provides a <tt>forbid_temporaries</tt> attribute to forbid
-temporaries of a particular type.</p>
-
-<blockquote>
-<pre>class __attribute__((forbid_temporaries)) scoped_lock {
-  ...
-};</pre>
-</blockquote>
-
-<p>This prevents mistakes like</p>
-
-<blockquote>
-<pre>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.
-};</pre>
-</blockquote>
-
-<p>Query for this feature with <tt>__has_attribute(forbid_temporaries)</tt>.
-Use <tt>-Wno-forbid-temporaries</tt> to disable the resulting warning.</p>
-
 <!-- ======================================================================= -->
 <h2 id="checking_language_features">Checks for Standard Language Features</h2>
 <!-- ======================================================================= -->
index 010736112d82a8d6ced402b2383dfec1b6254536..9b0982a29b9f0afb52ffd90eb99464e20b7da55a 100644 (file)
@@ -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">,
index cb87f0d5e6b61f65301439e6f6ec66e76a74ebe0..17bbc68afb7d4d561e317f7a82aaa091503b5486 100644 (file)
@@ -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<DiagGroup<"forbid-temporaries">>;
 
 // C++0x decltype
 def err_cannot_determine_declared_type_of_overloaded_function : Error<
index 7ed6ffcdaf0b9f03c7218cfaa3e83228fe2ed5a2..91389a4d9847c3c952689f794e3fe4ea80444982 100644 (file)
@@ -104,7 +104,6 @@ public:
     AT_dllimport,
     AT_ext_vector_type,
     AT_fastcall,
-    AT_forbid_temporaries,
     AT_format,
     AT_format_arg,
     AT_global,
index c3efda9a7a3afa659898f577d13eed0acb08ed28..77d962542bfc47b34b81468b2b0a5fd87aafe8ab 100644 (file)
@@ -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)
index 21d0f46528a32d867287718642f269407fbc3ce7..474c7cb82f9eb5ab20bc484f8bce39aeafe4806a 100644 (file)
@@ -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<TypeDecl>(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<ParmVarDecl>(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;
index 8581c6f649482fb156d71a55b355be9ad6779d87..e95bad4d0a698d730bf15fdd07a4955f730625c1 100644 (file)
@@ -3294,12 +3294,9 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) {
     }
   }
 
-  CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-  if (RD->getAttr<ForbidTemporariesAttr>())
-    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<CXXRecordDecl>(RT->getDecl());
   if (RD->isInvalidDecl() || RD->hasTrivialDestructor())
     return Owned(E);
 
diff --git a/test/SemaCXX/forbid-temporaries.cpp b/test/SemaCXX/forbid-temporaries.cpp
deleted file mode 100644 (file)
index cbe47ae..0000000
+++ /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<typename T>
-class __attribute__((forbid_temporaries)) NotATemporaryTpl {
-};
-
-template<typename T>
-void bar_tpl(const NotATemporaryTpl<T>&);
-
-void tpl_user() {
-  NotATemporaryTpl<int> this_is_fine;
-  bar_tpl(NotATemporaryTpl<int>());  // expected-warning {{must not create temporaries of type 'NotATemporaryTpl<int>'}}
-  NotATemporaryTpl<int>();   // expected-warning {{must not create temporaries of type 'NotATemporaryTpl<int>'}}
-}
-
-
-// Test that a specialization can override the template's default.
-struct TemporariesOk;
-template<> class NotATemporaryTpl<TemporariesOk> {
-};
-
-void specialization_user() {
-  NotATemporaryTpl<TemporariesOk> this_is_fine;
-  bar_tpl(NotATemporaryTpl<TemporariesOk>());
-  NotATemporaryTpl<TemporariesOk>();
-}