Browse Source

Add more warnings to for the ObjC runtime build

Working on https://github.com/google/protobuf/issues/1599, specifically:
- Turn on more warnings that the Xcode UI calls out with individual controls.
- Manually add:
  -Wundef
  -Wswitch-enum
- Manually add and then diable in the unittests because of XCTest's headers:
  -Wreserved-id-macro
  -Wdocumentation-unknown-command
- Manually add -Wdirect-ivar-access, but disable it for the unittests and in
  the library code (via #pragmas to suppress it). This is done so proto users
  can enable the warning.
Thomas Van Lenten 9 years ago
parent
commit
c8a440dfb6

+ 8 - 0
objectivec/GPBArray.m

@@ -32,6 +32,12 @@
 
 #import "GPBMessage_PackagePrivate.h"
 
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
 // Mutable arrays use an internal buffer that can always hold a multiple of this elements.
 #define kChunkSize 16
 #define CapacityFromCount(x) (((x / kChunkSize) + 1) * kChunkSize)
@@ -2532,3 +2538,5 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
 }
 
 @end
+
+#pragma clang diagnostic pop

+ 1 - 1
objectivec/GPBBootstrap.h

@@ -48,7 +48,7 @@
 // doesn't allow us to forward declare. We work around this one case by
 // providing a local definition. The default case has to use NS_ENUM for the
 // magic that is Swift bridging of enums.
-#if (__cplusplus && __cplusplus < 201103L)
+#if (defined(__cplusplus) && __cplusplus && __cplusplus < 201103L)
  #define GPB_ENUM(X) enum X : int32_t X; enum X : int32_t
 #else
  #define GPB_ENUM(X) NS_ENUM(int32_t, X)

+ 1 - 1
objectivec/GPBCodedInputStream.h

@@ -93,7 +93,7 @@ NS_ASSUME_NONNULL_BEGIN
 ///
 /// @param message           The message to set fields on as they are read.
 /// @param extensionRegistry An optional extension registry to use to lookup
-///                          extensions for @message.
+///                          extensions for @c message.
 - (void)readMessage:(GPBMessage *)message
   extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry;
 

+ 8 - 0
objectivec/GPBCodedInputStream.m

@@ -316,6 +316,12 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
   [super dealloc];
 }
 
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
 - (int32_t)readTag {
   return GPBCodedInputStreamReadTag(&state_);
 }
@@ -496,4 +502,6 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
   return GPBCodedInputStreamReadSInt64(&state_);
 }
 
+#pragma clang diagnostic pop
+
 @end

+ 9 - 1
objectivec/GPBCodedOutputStream.m

@@ -144,7 +144,7 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
   GPBWriteRawByte(state, (int32_t)(value >> 56) & 0xFF);
 }
 
-#if DEBUG && !defined(NS_BLOCK_ASSERTIONS)
+#if defined(DEBUG) && DEBUG && !defined(NS_BLOCK_ASSERTIONS)
 + (void)load {
   // This test exists to verify that CFStrings with embedded NULLs will work
   // for us. If this Assert fails, all code below that depends on
@@ -203,6 +203,12 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
   return [[[self alloc] initWithData:data] autorelease];
 }
 
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
 - (void)writeDoubleNoTag:(double)value {
   GPBWriteRawLittleEndian64(&state_, GPBConvertDoubleToInt64(value));
 }
@@ -981,6 +987,8 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
   GPBWriteRawLittleEndian64(&state_, value);
 }
 
+#pragma clang diagnostic pop
+
 @end
 
 size_t GPBComputeDoubleSizeNoTag(Float64 value) {

+ 1 - 1
objectivec/GPBDescriptor.h

@@ -135,7 +135,7 @@ typedef NS_ENUM(uint8_t, GPBFieldType) {
 @property(nonatomic, readonly, assign) Class msgClass;
 @property(nonatomic, readonly) NSString *singletonName;
 @property(nonatomic, readonly, strong, nullable) GPBEnumDescriptor *enumDescriptor;
-@property(nonatomic, readonly) id defaultValue;
+@property(nonatomic, readonly, nullable) id defaultValue;
 @end
 
 NS_ASSUME_NONNULL_END

+ 9 - 1
objectivec/GPBDescriptor.m

@@ -36,6 +36,12 @@
 #import "GPBWireFormat.h"
 #import "GPBMessage_PackagePrivate.h"
 
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
 // The address of this variable is used as a key for obj_getAssociatedObject.
 static const char kTextFormatExtraValueKey = 0;
 
@@ -803,7 +809,7 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
   if ((self = [super init])) {
     description_ = description;
 
-#if DEBUG
+#if defined(DEBUG) && DEBUG
     const char *className = description->messageOrGroupClassName;
     if (className) {
       NSAssert(objc_lookUpClass(className) != Nil,
@@ -961,3 +967,5 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
 }
 
 @end
+
+#pragma clang diagnostic pop

+ 19 - 11
objectivec/GPBDescriptor_PackagePrivate.h

@@ -245,6 +245,12 @@ typedef NS_OPTIONS(uint32_t, GPBDescriptorInitializationFlags) {
 
 CF_EXTERN_C_BEGIN
 
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
 GPB_INLINE BOOL GPBFieldIsMapOrArray(GPBFieldDescriptor *field) {
   return (field->description_->flags &
           (GPBFieldRepeated | GPBFieldMapKeyMask)) != 0;
@@ -262,6 +268,8 @@ GPB_INLINE uint32_t GPBFieldNumber(GPBFieldDescriptor *field) {
   return field->description_->number;
 }
 
+#pragma clang diagnostic pop
+
 uint32_t GPBFieldTag(GPBFieldDescriptor *self);
 
 // For repeated fields, alternateWireType is the wireType with the opposite
@@ -291,23 +299,23 @@ GPB_INLINE BOOL GPBExtensionIsWireFormat(GPBExtensionDescription *description) {
 }
 
 // Helper for compile time assets.
-#ifndef _GPBCompileAssert
+#ifndef GPBInternalCompileAssert
   #if __has_feature(c_static_assert) || __has_extension(c_static_assert)
-    #define _GPBCompileAssert(test, msg) _Static_assert((test), #msg)
+    #define GPBInternalCompileAssert(test, msg) _Static_assert((test), #msg)
   #else
     // Pre-Xcode 7 support.
-    #define _GPBCompileAssertSymbolInner(line, msg) _GPBCompileAssert ## line ## __ ## msg
-    #define _GPBCompileAssertSymbol(line, msg) _GPBCompileAssertSymbolInner(line, msg)
-    #define _GPBCompileAssert(test, msg) \
-        typedef char _GPBCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]
+    #define GPBInternalCompileAssertSymbolInner(line, msg) GPBInternalCompileAssert ## line ## __ ## msg
+    #define GPBInternalCompileAssertSymbol(line, msg) GPBInternalCompileAssertSymbolInner(line, msg)
+    #define GPBInternalCompileAssert(test, msg) \
+        typedef char GPBInternalCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]
   #endif  // __has_feature(c_static_assert) || __has_extension(c_static_assert)
-#endif // _GPBCompileAssert
+#endif // GPBInternalCompileAssert
 
 // Sanity check that there isn't padding between the field description
 // structures with and without a default.
-_GPBCompileAssert(sizeof(GPBMessageFieldDescriptionWithDefault) ==
-                  (sizeof(GPBGenericValue) +
-                   sizeof(GPBMessageFieldDescription)),
-                  DescriptionsWithDefault_different_size_than_expected);
+GPBInternalCompileAssert(sizeof(GPBMessageFieldDescriptionWithDefault) ==
+                         (sizeof(GPBGenericValue) +
+                          sizeof(GPBMessageFieldDescription)),
+                         DescriptionsWithDefault_different_size_than_expected);
 
 CF_EXTERN_C_END

+ 11 - 0
objectivec/GPBDictionary.m

@@ -45,6 +45,12 @@
 // directly.
 // ------------------------------------------------------------------
 
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
 // Used to include code only visible to specific versions of the static
 // analyzer. Useful for wrapping code that only exists to silence the analyzer.
 // Determine the values you want to use for BEGIN_APPLE_BUILD_VERSION,
@@ -484,6 +490,8 @@ void GPBDictionaryReadEntry(id mapDictionary,
       key.valueString = [@"" retain];
     }
     if (GPBDataTypeIsObject(valueDataType) && value.valueString == nil) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wswitch-enum"
       switch (valueDataType) {
         case GPBDataTypeString:
           value.valueString = [@"" retain];
@@ -505,6 +513,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
           // Nothing
           break;
       }
+#pragma clang diagnostic pop
     }
 
     if ((keyDataType == GPBDataTypeString) && GPBDataTypeIsObject(valueDataType)) {
@@ -13553,3 +13562,5 @@ void GPBDictionaryReadEntry(id mapDictionary,
 }
 
 @end
+
+#pragma clang diagnostic pop

+ 11 - 0
objectivec/GPBExtensionInternals.m

@@ -45,6 +45,8 @@ static id NewSingleValueFromInputStream(GPBExtensionDescriptor *extension,
     __attribute__((ns_returns_retained));
 
 GPB_INLINE size_t DataTypeSize(GPBDataType dataType) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wswitch-enum"
   switch (dataType) {
     case GPBDataTypeBool:
       return 1;
@@ -59,6 +61,7 @@ GPB_INLINE size_t DataTypeSize(GPBDataType dataType) {
     default:
       return 0;
   }
+#pragma clang diagnostic pop
 }
 
 static size_t ComputePBSerializedSizeNoTagOfObject(GPBDataType dataType, id object) {
@@ -261,6 +264,12 @@ static void WriteArrayIncludingTagsToCodedOutputStream(
   }
 }
 
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
 void GPBExtensionMergeFromInputStream(GPBExtensionDescriptor *extension,
                                       BOOL isPackedOnStream,
                                       GPBCodedInputStream *input,
@@ -378,3 +387,5 @@ static id NewSingleValueFromInputStream(GPBExtensionDescriptor *extension,
 
   return nil;
 }
+
+#pragma clang diagnostic pop

+ 8 - 0
objectivec/GPBExtensionRegistry.m

@@ -51,6 +51,12 @@
   [super dealloc];
 }
 
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
 - (instancetype)copyWithZone:(NSZone *)zone {
   GPBExtensionRegistry *result = [[[self class] allocWithZone:zone] init];
   if (result && mutableClassMap_.count) {
@@ -105,4 +111,6 @@
   }
 }
 
+#pragma clang diagnostic pop
+
 @end

+ 15 - 7
objectivec/GPBMessage.m

@@ -44,6 +44,12 @@
 #import "GPBUnknownFieldSet_PackagePrivate.h"
 #import "GPBUtilities_PackagePrivate.h"
 
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
 NSString *const GPBMessageErrorDomain =
     GPBNSStringifySymbol(GPBMessageErrorDomain);
 
@@ -694,7 +700,7 @@ void GPBClearMessageAutocreator(GPBMessage *self) {
     return;
   }
 
-#if DEBUG && !defined(NS_BLOCK_ASSERTIONS)
+#if defined(DEBUG) && DEBUG && !defined(NS_BLOCK_ASSERTIONS)
   // Either the autocreator must have its "has" flag set to YES, or it must be
   // NO and not equal to ourselves.
   BOOL autocreatorHas =
@@ -1736,7 +1742,7 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
 }
 
 - (BOOL)hasExtension:(GPBExtensionDescriptor *)extension {
-#if DEBUG
+#if defined(DEBUG) && DEBUG
   CheckExtension(self, extension);
 #endif  // DEBUG
   return nil != [extensionMap_ objectForKey:extension];
@@ -2621,7 +2627,7 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
         case GPBDataTypeFixed32:
         case GPBDataTypeUInt32:
         case GPBDataTypeFloat: {
-          _GPBCompileAssert(sizeof(float) == sizeof(uint32_t), float_not_32_bits);
+          GPBInternalCompileAssert(sizeof(float) == sizeof(uint32_t), float_not_32_bits);
           // These are all 32bit, signed/unsigned doesn't matter for equality.
           uint32_t *selfValPtr = (uint32_t *)&selfStorage[fieldOffset];
           uint32_t *otherValPtr = (uint32_t *)&otherStorage[fieldOffset];
@@ -2636,7 +2642,7 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
         case GPBDataTypeFixed64:
         case GPBDataTypeUInt64:
         case GPBDataTypeDouble: {
-          _GPBCompileAssert(sizeof(double) == sizeof(uint64_t), double_not_64_bits);
+          GPBInternalCompileAssert(sizeof(double) == sizeof(uint64_t), double_not_64_bits);
           // These are all 64bit, signed/unsigned doesn't matter for equality.
           uint64_t *selfValPtr = (uint64_t *)&selfStorage[fieldOffset];
           uint64_t *otherValPtr = (uint64_t *)&otherStorage[fieldOffset];
@@ -2733,7 +2739,7 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
         case GPBDataTypeFixed32:
         case GPBDataTypeUInt32:
         case GPBDataTypeFloat: {
-          _GPBCompileAssert(sizeof(float) == sizeof(uint32_t), float_not_32_bits);
+          GPBInternalCompileAssert(sizeof(float) == sizeof(uint32_t), float_not_32_bits);
           // These are all 32bit, just mix it in.
           uint32_t *valPtr = (uint32_t *)&storage[fieldOffset];
           result = prime * result + *valPtr;
@@ -2745,7 +2751,7 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
         case GPBDataTypeFixed64:
         case GPBDataTypeUInt64:
         case GPBDataTypeDouble: {
-          _GPBCompileAssert(sizeof(double) == sizeof(uint64_t), double_not_64_bits);
+          GPBInternalCompileAssert(sizeof(double) == sizeof(uint64_t), double_not_64_bits);
           // These are all 64bit, just mix what fits into an NSUInteger in.
           uint64_t *valPtr = (uint64_t *)&storage[fieldOffset];
           result = prime * result + (NSUInteger)(*valPtr);
@@ -2792,7 +2798,7 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
   return description;
 }
 
-#if DEBUG
+#if defined(DEBUG) && DEBUG
 
 // Xcode 5.1 added support for custom quick look info.
 // https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/CustomClassDisplay_in_QuickLook/CH01-quick_look_for_custom_objects/CH01-quick_look_for_custom_objects.html#//apple_ref/doc/uid/TP40014001-CH2-SW1
@@ -3182,3 +3188,5 @@ static void ResolveIvarSet(GPBFieldDescriptor *field,
 }
 
 @end
+
+#pragma clang diagnostic pop

+ 3 - 0
objectivec/GPBMessage_PackagePrivate.h

@@ -110,9 +110,12 @@ CF_EXTERN_C_BEGIN
 
 // Call this before using the readOnlySemaphore_. This ensures it is created only once.
 NS_INLINE void GPBPrepareReadOnlySemaphore(GPBMessage *self) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
   dispatch_once(&self->readOnlySemaphoreCreationOnce_, ^{
     self->readOnlySemaphore_ = dispatch_semaphore_create(1);
   });
+#pragma clang diagnostic pop
 }
 
 // Returns a new instance that was automatically created by |autocreator| for

+ 8 - 0
objectivec/GPBUnknownField.m

@@ -67,6 +67,12 @@
   [super dealloc];
 }
 
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
 - (id)copyWithZone:(NSZone *)zone {
   GPBUnknownField *result =
       [[GPBUnknownField allocWithZone:zone] initWithNumber:number_];
@@ -323,4 +329,6 @@
   }
 }
 
+#pragma clang diagnostic pop
+
 @end

+ 9 - 1
objectivec/GPBUnknownFieldSet.m

@@ -93,6 +93,12 @@ static void CopyWorker(const void *key, const void *value, void *context) {
   [copied release];
 }
 
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
 - (id)copyWithZone:(NSZone *)zone {
   GPBUnknownFieldSet *result = [[GPBUnknownFieldSet allocWithZone:zone] init];
   if (fields_) {
@@ -148,7 +154,7 @@ static void CopyWorker(const void *key, const void *value, void *context) {
 }
 
 - (NSArray *)sortedFields {
-  if (!fields_) return nil;
+  if (!fields_) return [NSArray array];
   size_t count = CFDictionaryGetCount(fields_);
   ssize_t keys[count];
   GPBUnknownField *values[count];
@@ -420,4 +426,6 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key,
   }
 }
 
+#pragma clang diagnostic pop
+
 @end

+ 19 - 5
objectivec/GPBUtilities.m

@@ -39,6 +39,12 @@
 #import "GPBUnknownField.h"
 #import "GPBUnknownFieldSet.h"
 
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
 static void AppendTextFormatForMessage(GPBMessage *message,
                                        NSMutableString *toStr,
                                        NSString *lineIndent);
@@ -891,7 +897,7 @@ void GPBSetMessageGroupField(GPBMessage *self,
 
 // Only exists for public api, no core code should use this.
 id GPBGetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field) {
-#if DEBUG
+#if defined(DEBUG) && DEBUG
   if (field.fieldType != GPBFieldTypeRepeated) {
     [NSException raise:NSInvalidArgumentException
                 format:@"%@.%@ is not a repeated field.",
@@ -903,7 +909,7 @@ id GPBGetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field) {
 
 // Only exists for public api, no core code should use this.
 void GPBSetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field, id array) {
-#if DEBUG
+#if defined(DEBUG) && DEBUG
   if (field.fieldType != GPBFieldTypeRepeated) {
     [NSException raise:NSInvalidArgumentException
                 format:@"%@.%@ is not a repeated field.",
@@ -957,7 +963,7 @@ void GPBSetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field, id
   GPBSetObjectIvarWithField(self, field, array);
 }
 
-#if DEBUG
+#if defined(DEBUG) && DEBUG
 static NSString *TypeToStr(GPBDataType dataType) {
   switch (dataType) {
     case GPBDataTypeBool:
@@ -993,7 +999,7 @@ static NSString *TypeToStr(GPBDataType dataType) {
 
 // Only exists for public api, no core code should use this.
 id GPBGetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field) {
-#if DEBUG
+#if defined(DEBUG) && DEBUG
   if (field.fieldType != GPBFieldTypeMap) {
     [NSException raise:NSInvalidArgumentException
                 format:@"%@.%@ is not a map<> field.",
@@ -1006,7 +1012,7 @@ id GPBGetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field) {
 // Only exists for public api, no core code should use this.
 void GPBSetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field,
                            id dictionary) {
-#if DEBUG
+#if defined(DEBUG) && DEBUG
   if (field.fieldType != GPBFieldTypeMap) {
     [NSException raise:NSInvalidArgumentException
                 format:@"%@.%@ is not a map<> field.",
@@ -1133,6 +1139,8 @@ static void AppendTextFormatForMapMessageField(
       [toStr appendString:@"\n"];
 
       [toStr appendString:valueLine];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wswitch-enum"
       switch (valueDataType) {
         case GPBDataTypeString:
           AppendStringEscaped(value, toStr);
@@ -1153,6 +1161,7 @@ static void AppendTextFormatForMapMessageField(
           NSCAssert(NO, @"Can't happen");
           break;
       }
+#pragma clang diagnostic pop
       [toStr appendString:@"\n"];
 
       [toStr appendString:msgEnd];
@@ -1174,6 +1183,8 @@ static void AppendTextFormatForMapMessageField(
       }
 
       [toStr appendString:valueLine];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wswitch-enum"
       switch (valueDataType) {
         case GPBDataTypeString:
           AppendStringEscaped(valueObj, toStr);
@@ -1211,6 +1222,7 @@ static void AppendTextFormatForMapMessageField(
           [toStr appendString:valueObj];
           break;
       }
+#pragma clang diagnostic pop
       [toStr appendString:@"\n"];
 
       [toStr appendString:msgEnd];
@@ -1706,6 +1718,8 @@ NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key,
   return result;
 }
 
+#pragma clang diagnostic pop
+
 #pragma mark - GPBMessageSignatureProtocol
 
 // A series of selectors that are used solely to get @encoding values

+ 7 - 1
objectivec/GPBUtilities_PackagePrivate.h

@@ -52,7 +52,7 @@ CF_EXTERN_C_BEGIN
 // generated sources to make sure they are linked with a supporting runtime.
 void GPBCheckRuntimeVersionInternal(int32_t version);
 GPB_INLINE void GPBDebugCheckRuntimeVersion() {
-#if DEBUG
+#if defined(DEBUG) && DEBUG
   GPBCheckRuntimeVersionInternal(GOOGLE_PROTOBUF_OBJC_GEN_VERSION);
 #endif
 }
@@ -125,6 +125,10 @@ GPB_INLINE uint64_t GPBEncodeZigZag64(int64_t n) {
   return (n << 1) ^ (n >> 63);
 }
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wswitch-enum"
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
 GPB_INLINE BOOL GPBDataTypeIsObject(GPBDataType type) {
   switch (type) {
     case GPBDataTypeBytes:
@@ -187,6 +191,8 @@ GPB_INLINE void GPBSetHasIvarField(GPBMessage *self, GPBFieldDescriptor *field,
 void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
                         int32_t oneofHasIndex, uint32_t fieldNumberNotToClear);
 
+#pragma clang diagnostic pop
+
 //%PDDM-DEFINE GPB_IVAR_SET_DECL(NAME, TYPE)
 //%void GPBSet##NAME##IvarWithFieldInternal(GPBMessage *self,
 //%            NAME$S                     GPBFieldDescriptor *field,

+ 38 - 0
objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj

@@ -749,6 +749,12 @@
 				PRODUCT_NAME = UnitTests;
 				SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
 				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+				WARNING_CFLAGS = (
+					"$(inherited)",
+					"-Wno-documentation-unknown-command",
+					"-Wno-reserved-id-macro",
+					"-Wno-direct-ivar-access",
+				);
 			};
 			name = Debug;
 		};
@@ -766,6 +772,12 @@
 				PRODUCT_BUNDLE_IDENTIFIER = "com.yourcompany.${PRODUCT_NAME:identifier}";
 				PRODUCT_NAME = UnitTests;
 				SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
+				WARNING_CFLAGS = (
+					"$(inherited)",
+					"-Wno-documentation-unknown-command",
+					"-Wno-reserved-id-macro",
+					"-Wno-direct-ivar-access",
+				);
 			};
 			name = Release;
 		};
@@ -773,15 +785,20 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = YES;
+				CLANG_ANALYZER_NONNULL = YES;
 				CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
 				CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
 				CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
 				CLANG_STATIC_ANALYZER_MODE = deep;
 				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
 				CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
 				CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
 				CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				ENABLE_TESTABILITY = YES;
 				GCC_C_LANGUAGE_STANDARD = c99;
@@ -802,6 +819,7 @@
 				GCC_WARN_SHADOW = YES;
 				GCC_WARN_SIGN_COMPARE = YES;
 				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNKNOWN_PRAGMAS = YES;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_LABEL = YES;
@@ -812,6 +830,13 @@
 				ONLY_ACTIVE_ARCH = YES;
 				RUN_CLANG_STATIC_ANALYZER = YES;
 				SDKROOT = macosx;
+				WARNING_CFLAGS = (
+					"-Wdocumentation-unknown-command",
+					"-Wundef",
+					"-Wreserved-id-macro",
+					"-Wswitch-enum",
+					"-Wdirect-ivar-access",
+				);
 			};
 			name = Debug;
 		};
@@ -819,15 +844,20 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = YES;
+				CLANG_ANALYZER_NONNULL = YES;
 				CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
 				CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
 				CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
 				CLANG_STATIC_ANALYZER_MODE = deep;
 				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
 				CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
 				CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
 				CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				ENABLE_NS_ASSERTIONS = NO;
 				GCC_C_LANGUAGE_STANDARD = c99;
@@ -846,6 +876,7 @@
 				GCC_WARN_SHADOW = YES;
 				GCC_WARN_SIGN_COMPARE = YES;
 				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNKNOWN_PRAGMAS = YES;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_LABEL = YES;
@@ -855,6 +886,13 @@
 				MACOSX_DEPLOYMENT_TARGET = 10.9;
 				RUN_CLANG_STATIC_ANALYZER = YES;
 				SDKROOT = macosx;
+				WARNING_CFLAGS = (
+					"-Wdocumentation-unknown-command",
+					"-Wundef",
+					"-Wreserved-id-macro",
+					"-Wswitch-enum",
+					"-Wdirect-ivar-access",
+				);
 			};
 			name = Release;
 		};

+ 38 - 0
objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj

@@ -901,6 +901,12 @@
 				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
 				TARGETED_DEVICE_FAMILY = "1,2";
 				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iOSTestHarness.app/iOSTestHarness";
+				WARNING_CFLAGS = (
+					"$(inherited)",
+					"-Wno-documentation-unknown-command",
+					"-Wno-reserved-id-macro",
+					"-Wno-direct-ivar-access",
+				);
 			};
 			name = Debug;
 		};
@@ -928,6 +934,12 @@
 				SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
 				TARGETED_DEVICE_FAMILY = "1,2";
 				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iOSTestHarness.app/iOSTestHarness";
+				WARNING_CFLAGS = (
+					"$(inherited)",
+					"-Wno-documentation-unknown-command",
+					"-Wno-reserved-id-macro",
+					"-Wno-direct-ivar-access",
+				);
 			};
 			name = Release;
 		};
@@ -935,15 +947,20 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = YES;
+				CLANG_ANALYZER_NONNULL = YES;
 				CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
 				CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
 				CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
 				CLANG_STATIC_ANALYZER_MODE = deep;
 				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
 				CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
 				CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
 				CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				ENABLE_TESTABILITY = YES;
@@ -965,6 +982,7 @@
 				GCC_WARN_SHADOW = YES;
 				GCC_WARN_SIGN_COMPARE = YES;
 				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNKNOWN_PRAGMAS = YES;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_LABEL = YES;
@@ -975,6 +993,13 @@
 				ONLY_ACTIVE_ARCH = YES;
 				RUN_CLANG_STATIC_ANALYZER = YES;
 				SDKROOT = iphoneos;
+				WARNING_CFLAGS = (
+					"-Wdocumentation-unknown-command",
+					"-Wundef",
+					"-Wreserved-id-macro",
+					"-Wswitch-enum",
+					"-Wdirect-ivar-access",
+				);
 			};
 			name = Debug;
 		};
@@ -982,15 +1007,20 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = YES;
+				CLANG_ANALYZER_NONNULL = YES;
 				CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
 				CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
 				CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
 				CLANG_STATIC_ANALYZER_MODE = deep;
 				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
 				CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
 				CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
 				CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				ENABLE_NS_ASSERTIONS = NO;
@@ -1010,6 +1040,7 @@
 				GCC_WARN_SHADOW = YES;
 				GCC_WARN_SIGN_COMPARE = YES;
 				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNKNOWN_PRAGMAS = YES;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_LABEL = YES;
@@ -1019,6 +1050,13 @@
 				IPHONEOS_DEPLOYMENT_TARGET = 6.1;
 				RUN_CLANG_STATIC_ANALYZER = YES;
 				SDKROOT = iphoneos;
+				WARNING_CFLAGS = (
+					"-Wdocumentation-unknown-command",
+					"-Wundef",
+					"-Wreserved-id-macro",
+					"-Wswitch-enum",
+					"-Wdirect-ivar-access",
+				);
 			};
 			name = Release;
 		};

+ 1 - 0
objectivec/google/protobuf/Struct.pbobjc.m

@@ -22,6 +22,7 @@
 
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
 
 #pragma mark - GPBStructRoot
 

+ 26 - 2
src/google/protobuf/compiler/objectivec/objectivec_file.cc

@@ -182,6 +182,10 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
     import_writer.Print(printer);
   }
 
+  // Note:
+  //  deprecated-declarations suppression is only needed if some place in this
+  //    proto file is something deprecated or if it references something from
+  //    another file that is deprecated.
   printer->Print(
       "// @@protoc_insertion_point(imports)\n"
       "\n"
@@ -292,14 +296,34 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
     import_writer.Print(printer);
   }
 
+  bool includes_oneof = false;
+  for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
+       iter != message_generators_.end(); ++iter) {
+    if ((*iter)->IncludesOneOfDefinition()) {
+      includes_oneof = true;
+      break;
+    }
+  }
+
+  // Note:
+  //  deprecated-declarations suppression is only needed if some place in this
+  //    proto file is something deprecated or if it references something from
+  //    another file that is deprecated.
   printer->Print(
       "// @@protoc_insertion_point(imports)\n"
       "\n"
       "#pragma clang diagnostic push\n"
-      "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n"
-      "\n");
+      "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n");
+  if (includes_oneof) {
+    // The generated code for oneof's uses direct ivar access, suppress the
+    // warning incase developer turn that on in the context they compile the
+    // generated code.
+    printer->Print(
+        "#pragma clang diagnostic ignored \"-Wdirect-ivar-access\"\n");
+  }
 
   printer->Print(
+      "\n"
       "#pragma mark - $root_class_name$\n"
       "\n"
       "@implementation $root_class_name$\n\n",

+ 16 - 0
src/google/protobuf/compiler/objectivec/objectivec_message.cc

@@ -246,6 +246,22 @@ void MessageGenerator::DetermineForwardDeclarations(set<string>* fwd_decls) {
   }
 }
 
+bool MessageGenerator::IncludesOneOfDefinition() const {
+  if (!oneof_generators_.empty()) {
+    return true;
+  }
+
+  for (vector<MessageGenerator*>::const_iterator iter =
+           nested_message_generators_.begin();
+       iter != nested_message_generators_.end(); ++iter) {
+    if ((*iter)->IncludesOneOfDefinition()) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 void MessageGenerator::GenerateEnumHeader(io::Printer* printer) {
   for (vector<EnumGenerator*>::iterator iter = enum_generators_.begin();
        iter != enum_generators_.end(); ++iter) {

+ 3 - 0
src/google/protobuf/compiler/objectivec/objectivec_message.h

@@ -66,6 +66,9 @@ class MessageGenerator {
   void GenerateExtensionRegistrationSource(io::Printer* printer);
   void DetermineForwardDeclarations(set<string>* fwd_decls);
 
+  // Checks if the message or a nested message includes a oneof definition.
+  bool IncludesOneOfDefinition() const;
+
  private:
   void GenerateParseFromMethodsHeader(io::Printer* printer);