diff options
author | Jooyung Han <jooyung@google.com> | 2020-12-30 12:29:31 +0900 |
---|---|---|
committer | Jooyung Han <jooyung@google.com> | 2020-12-31 11:12:12 +0900 |
commit | d25527a4f81ceccabbea47ff40a5159b47a36130 (patch) | |
tree | ae5dbc539636d1cf8fb8b3474b62b821ada342b4 /diagnostics.cpp | |
parent | 4585445f323026f4195f2b44cc2cdcab103c6f64 (diff) | |
download | aidl-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.cpp | 34 |
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; } |