aboutsummaryrefslogtreecommitdiff
path: root/diagnostics.cpp
diff options
context:
space:
mode:
authorJooyung Han <jooyung@google.com>2020-12-30 12:29:31 +0900
committerJooyung Han <jooyung@google.com>2020-12-31 11:12:12 +0900
commitd25527a4f81ceccabbea47ff40a5159b47a36130 (patch)
treeae5dbc539636d1cf8fb8b3474b62b821ada342b4 /diagnostics.cpp
parent4585445f323026f4195f2b44cc2cdcab103c6f64 (diff)
downloadaidl-d25527a4f81ceccabbea47ff40a5159b47a36130.tar.gz
add -Wexplicit-default
When eanbled, this warns variables with no default value while they can have a default value. For example, primitive types are zero-intialized when they don't have default value set. But we recommend set default values explicitly. For now some types can't have default value. For example, parcelables can't have default value. Bug: 168028537 Test: aidl_unittests Change-Id: I74edff39526135c90d417785bba716e95fccb786
Diffstat (limited to 'diagnostics.cpp')
-rw-r--r--diagnostics.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/diagnostics.cpp b/diagnostics.cpp
index 5579b70a..bf50cc2e 100644
--- a/diagnostics.cpp
+++ b/diagnostics.cpp
@@ -17,6 +17,7 @@
#include <functional>
#include <stack>
+#include <unordered_set>
#include "aidl_language.h"
#include "logging.h"
@@ -178,6 +179,38 @@ struct DiagnoseConstName : DiagnosticsVisitor {
}
};
+struct DiagnoseExplicitDefault : DiagnosticsVisitor {
+ DiagnoseExplicitDefault(DiagnosticsContext& diag) : DiagnosticsVisitor(diag) {}
+ void Visit(const AidlStructuredParcelable& p) override {
+ for (const auto& var : p.GetFields()) {
+ CheckExplicitDefault(*var);
+ }
+ }
+ void Visit(const AidlUnionDecl& u) override {
+ AIDL_FATAL_IF(u.GetFields().empty(), u) << "The union '" << u.GetName() << "' has no fields.";
+ const auto& first = u.GetFields()[0];
+ CheckExplicitDefault(*first);
+ }
+ void CheckExplicitDefault(const AidlVariableDeclaration& v) {
+ if (ShouldHaveExplicitDefault(v) && !v.IsDefaultUserSpecified()) {
+ diag.Report(v.GetLocation(), DiagnosticID::explicit_default)
+ << "The field '" << v.GetName() << "' has no explicit value.";
+ }
+ }
+ bool ShouldHaveExplicitDefault(const AidlVariableDeclaration& v) {
+ if (v.GetType().IsNullable()) return false;
+ if (v.GetType().IsArray()) return true;
+ if (auto type_name = v.GetType().GetName(); AidlTypenames::IsBuiltinTypename(type_name)) {
+ static const std::unordered_set<std::string> default_not_available = {
+ "IBinder", "ParcelableHolder", "ParcelFileDescriptor", "FileDescriptor", "List", "Map"};
+ return default_not_available.find(type_name) == default_not_available.end();
+ }
+ const auto defined_type = v.GetType().GetDefinedType();
+ AIDL_FATAL_IF(!defined_type, v);
+ return defined_type->AsEnumDeclaration() != nullptr;
+ }
+};
+
bool Diagnose(const AidlDocument& doc, const DiagnosticMapping& mapping) {
DiagnosticsContext diag(mapping);
@@ -185,6 +218,7 @@ bool Diagnose(const AidlDocument& doc, const DiagnosticMapping& mapping) {
DiagnoseEnumZero{diag}.Check(doc);
DiagnoseInoutParameter{diag}.Check(doc);
DiagnoseConstName{diag}.Check(doc);
+ DiagnoseExplicitDefault{diag}.Check(doc);
return diag.ErrorCount() == 0;
}