Alias,
Aligned,
AlwaysInline,
+ AnalyzerNoReturn, // Clang-specific.
Annotate,
AsmLabel, // Represent GCC asm label extension.
Blocks,
static bool classof(const Attr *A) { return A->getKind() == NoReturn; }
static bool classof(const NoReturnAttr *A) { return true; }
};
+
+class AnalyzerNoReturnAttr : public Attr {
+public:
+ AnalyzerNoReturnAttr() : Attr(AnalyzerNoReturn) {}
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) {
+ return A->getKind() == AnalyzerNoReturn;
+ }
+ static bool classof(const AnalyzerNoReturnAttr *A) { return true; }
+};
class DeprecatedAttr : public Attr {
public:
d->addAttr(::new (S.Context) AlwaysInlineAttr());
}
-static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
+ Sema &S, const char *attrName) {
// check the attribute arguments.
if (Attr.getNumArgs() != 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
- return;
+ return false;
}
if (!isFunctionOrMethod(d)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << "noreturn" << 0 /*function*/;
- return;
+ << attrName << 0 /*function*/;
+ return false;
}
- d->addAttr(::new (S.Context) NoReturnAttr());
+ return true;
+}
+
+static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+ if (HandleCommonNoReturnAttr(d, Attr, S, "noreturn"))
+ d->addAttr(::new (S.Context) NoReturnAttr());
+}
+
+static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
+ Sema &S) {
+ if (HandleCommonNoReturnAttr(d, Attr, S, "analyzer_noreturn"))
+ d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
}
static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break;
case AttributeList::AT_always_inline:
HandleAlwaysInlineAttr (D, Attr, S); break;
+ case AttributeList::AT_analyzer_noreturn:
+ HandleAnalyzerNoReturnAttr (D, Attr, S); break;
case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break;
case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break;
pr6708148_use(x); // no-warning
}
+// Handle both kinds of noreturn attributes for pruning paths.
+void rdar_6777003_noret() __attribute__((noreturn));
+void rdar_6777003_analyzer_noret() __attribute__((analyzer_noreturn));
+
+void rdar_6777003(int x) {
+ int *p = 0;
+
+ if (x == 1) {
+ rdar_6777003_noret();
+ *p = 1; // no-warning;
+ }
+
+ if (x == 2) {
+ rdar_6777003_analyzer_noret();
+ *p = 1; // no-warning;
+ }
+
+ *p = 1; // expected-warning{{Dereference of null pointer}}
+}
+