return;
BT.reset(new BugType(this, name, categories::UnixAPI));
}
+ void ReportOpenBug(CheckerContext &C,
+ ProgramStateRef State,
+ const char *Msg,
+ SourceRange SR) const;
};
} //end anonymous namespace
// "open" (man 2 open)
//===----------------------------------------------------------------------===//
+void UnixAPIChecker::ReportOpenBug(CheckerContext &C,
+ ProgramStateRef State,
+ const char *Msg,
+ SourceRange SR) const {
+ ExplodedNode *N = C.generateSink(State);
+ if (!N)
+ return;
+
+ LazyInitialize(BT_open, "Improper use of 'open'");
+
+ BugReport *Report = new BugReport(*BT_open, Msg, N);
+ Report->addRange(SR);
+ C.emitReport(Report);
+}
+
void UnixAPIChecker::CheckOpen(CheckerContext &C, const CallExpr *CE) const {
+ ProgramStateRef state = C.getState();
+
+ if (CE->getNumArgs() < 2) {
+ // The frontend should issue a warning for this case, so this is a sanity
+ // check.
+ return;
+ } else if (CE->getNumArgs() > 3) {
+ ReportOpenBug(C, state,
+ "Call to 'open' with more than three arguments",
+ CE->getArg(3)->getSourceRange());
+ return;
+ }
+
// The definition of O_CREAT is platform specific. We need a better way
// of querying this information from the checking environment.
if (!Val_O_CREAT.hasValue()) {
}
}
- // Look at the 'oflags' argument for the O_CREAT flag.
- ProgramStateRef state = C.getState();
-
- if (CE->getNumArgs() < 2) {
- // The frontend should issue a warning for this case, so this is a sanity
- // check.
- return;
- }
-
// Now check if oflags has O_CREAT set.
const Expr *oflagsEx = CE->getArg(1);
const SVal V = state->getSVal(oflagsEx, C.getLocationContext());
return;
if (CE->getNumArgs() < 3) {
- ExplodedNode *N = C.generateSink(trueState);
- if (!N)
- return;
-
- LazyInitialize(BT_open, "Improper use of 'open'");
-
- BugReport *report =
- new BugReport(*BT_open,
- "Call to 'open' requires a third argument when "
- "the 'O_CREAT' flag is set", N);
- report->addRange(oflagsEx->getSourceRange());
- C.emitReport(report);
+ ReportOpenBug(C, trueState,
+ "Call to 'open' requires a third argument when "
+ "the 'O_CREAT' flag is set",
+ oflagsEx->getSourceRange());
}
}
--- /dev/null
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.API -verify %s
+
+#ifndef O_RDONLY
+#define O_RDONLY 0
+#endif
+
+#ifndef NULL
+#define NULL ((void*) 0)
+#endif
+
+int open(const char *, int, ...);
+int close(int fildes);
+
+void open_1(const char *path) {
+ int fd;
+ fd = open(path, O_RDONLY); // no-warning
+ if (fd > -1)
+ close(fd);
+}
+
+void open_2(const char *path) {
+ int fd;
+ int mode = 0x0;
+ fd = open(path, O_RDONLY, mode, NULL); // expected-warning{{Call to 'open' with more than three arguments}}
+ if (fd > -1)
+ close(fd);
+}