[PATCH] D27424: Add the diagnose_if attribute to clang.

Aaron Ballman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 22 07:55:14 PST 2016


aaron.ballman added a comment.

I really like this attribute, thank you for working on it!



================
Comment at: include/clang/Basic/Attr.td:1584
+def DiagnoseIf : InheritableAttr {
+  let Spellings = [GNU<"diagnose_if">];
+  let Subjects = SubjectList<[Function]>;
----------------
I think this should also have a C++ spelling under the clang namespace.


================
Comment at: include/clang/Basic/AttrDocs.td:359
+  int val3 = abs(val);
+  int val4 = must_abs(val); // because run-time checks are not emitted for
+                            // diagnose_if attributes, this executes without
----------------
Capitalize the B in because.


================
Comment at: include/clang/Basic/DiagnosticCommonKinds.td:164
                           InGroup<GccCompat>;
+def ext_clang_diagnose_if : Extension<"'diagnose_if' is a clang extension">,
+                            InGroup<GccCompat>;
----------------
If we do add the clang namespaced spelling, we should have a test to ensure that this diagnostic is not triggered when the attribute is spelled `[[clang::diagnose_if(...)]]`.


================
Comment at: include/clang/Basic/DiagnosticSemaKinds.td:2145
+def err_diagnose_if_invalid_diagnostic_type : Error<
+  "invalid diagnostic type for diagnose_if. Try 'error' or 'warning'.">;
 def err_constexpr_body_no_return : Error<
----------------
Diagnostics don't have full stops, so I think a better way to write this is: `invalid diagnostic type for 'diagnose_if'; use \"error\" or \"warning\" instead`.


================
Comment at: include/clang/Basic/DiagnosticSemaKinds.td:3361
     "pass_object_size attribute">;
-def note_ovl_candidate_disabled_by_enable_if_attr : Note<
+def err_diagnose_if_succeeded: Error<"%0">;
+def warn_diagnose_if_succeeded : Warning<"%0">, InGroup<UserDefinedWarnings>;
----------------
Space before the colon.


================
Comment at: include/clang/Basic/DiagnosticSemaKinds.td:4380
     InGroup<DeprecatedDeclarations>;
+def note_from_diagnose_if : Note<"from diagnose_if attribute on %0:">;
 def warn_property_method_deprecated :
----------------
Please single quote the use of diagnose_if.


================
Comment at: include/clang/Sema/Overload.h:664
+
+    /// Basically an TinyPtrVector<DiagnoseIfAttr *> that doesn't own the
+    /// vector: If NumTriggeredDiagnoseIfs is 0 or 1, this is a DiagnoseIfAttr
----------------
an -> a


================
Comment at: include/clang/Sema/Sema.h:2616
+  DiagnoseIfAttr *
+  checkArgDependentDiagnoseIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
+                              SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal,
----------------
Can this (and the other new functions) accept the `FunctionDecl` as a `const FunctionDecl *` instead?


================
Comment at: lib/Sema/SemaDeclAttr.cpp:857
+public:
+  ParmVarDeclChecker(FunctionDecl *FD) {
+    Parms.insert(FD->param_begin(), FD->param_end());
----------------
This should accept `FD` as a const pointer.


================
Comment at: lib/Sema/SemaExpr.cpp:368
+
+    if (DiagnoseIfAttr *A =
+            checkArgIndependentDiagnoseIf(FD, DiagnoseIfWarnings)) {
----------------
`const DiagnoseIfAttr *`?


================
Comment at: lib/Sema/SemaExpr.cpp:388
+
+  for (DiagnoseIfAttr *W : DiagnoseIfWarnings)
+    emitDiagnoseIfDiagnostic(Loc, W);
----------------
`const auto *`?


================
Comment at: lib/Sema/SemaExpr.cpp:5186
+
+  for (DiagnoseIfAttr *Attr : Nonfatal)
+    S.emitDiagnoseIfDiagnostic(Fn->getLocStart(), Attr);
----------------
`const auto *`?


================
Comment at: lib/Sema/SemaOverload.cpp:827
   destroyCandidates();
-  ConversionSequenceAllocator.Reset();
-  NumInlineSequences = 0;
+  // DiagnoseIfAttrs are just pointers, so we don't need to destroy them.
+  SlabAllocator.Reset();
----------------
DiagnoseIfAttrs aren't the only thing allocated with the slab allocator though, right?  Since this is being generalized, I wonder if asserting somewhere that the slab allocator only deals with pointers would make sense?


================
Comment at: lib/Sema/SemaOverload.cpp:6151
+                                  bool MissingImplicitThis) {
+  auto EnableIfAttrs = getOrderedEnableIfAttrs(Function);
+  if (EnableIfAttrs.empty())
----------------
Please spell out the type instead of using `auto`, since the type isn't spelled in the initialization.


================
Comment at: lib/Sema/SemaOverload.cpp:6178-6179
+                                  SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal) {
+  for (Attr *A : Function->attrs())
+    if (auto *DIA = dyn_cast<DiagnoseIfAttr>(A))
+      if (ArgDependent == DIA->getArgDependent()) {
----------------
Instead of doing this, you can use `specific_attrs<DiagnoseIfAttr>()`


================
Comment at: lib/Sema/SemaOverload.cpp:9009
+static bool isCandidateUnavailableDueToDiagnoseIf(const OverloadCandidate &OC) {
+  return OC.NumTriggeredDiagnoseIfs == 1 &&
+         OC.DiagnoseIfInfo.get<DiagnoseIfAttr *>()->isError();
----------------
Can you run into a situation with stacked diagnose_if errors, so that there's > 1?


================
Comment at: lib/Sema/SemaOverload.cpp:9101
 
+  for (DiagnoseIfAttr *W : Best->getDiagnoseIfInfo()) {
+    assert(W->isWarning() && "Errors should've been caught earlier!");
----------------
Can use `const auto *` here.


================
Comment at: lib/Sema/SemaOverload.cpp:12672
+
+    for (DiagnoseIfAttr *Attr : Nonfatal)
+      emitDiagnoseIfDiagnostic(MemE->getMemberLoc(), Attr);
----------------
Can use `const auto *` here.


================
Comment at: lib/Sema/SemaTemplateInstantiateDecl.cpp:193
+    S.Diag(A->getLocation(), diag::err_attr_cond_never_constant_expr)
+        << A->getSpelling();
+    for (const PartialDiagnosticAt &P : Diags)
----------------
You shouldn't have to use `getSpelling()` here; I believe the diagnostics engine has an overload to properly handle `Attr *` objects.


================
Comment at: lib/Sema/SemaTemplateInstantiateDecl.cpp:194
+        << A->getSpelling();
+    for (const PartialDiagnosticAt &P : Diags)
+      S.Diag(P.first, P.second);
----------------
`const auto &`


https://reviews.llvm.org/D27424





More information about the cfe-commits mailing list