8 Replies
      Latest reply on Jul 16, 2019 5:29 PM by john daniel
      yetanothermeagain Level 1 Level 1 (0 points)

        Xcode (tested with 10, and Xcode 11 Betas) allows a pointer to NSDictionary* (a pointer to a pointer) be used instead of a pointer to NSMutableDictionary*, which leads to a runtime crash instead of expected compilation error. I submitted a bug about it, but the bug returned with "works with clang-1001.0.46.3 which is part of Xcode 10.2". i wonder what that means to me as I do not use clang in terminal, only via Xcode. Can / should I somehow change the clang version that is used by Xcode?

         

        a side question, are there several versions of clang installed with Xcode and for whatever reason Xcode is not using the latest one?

         

        void foo(NSMutableDictionary** mutableDictionary) {

            (*mutableDictionary)[@"hello"] = @"world";

        }

         

        ...

            NSDictionary* dictionary = [NSDictionary new];

            foo(&dictionary); // no compilation error here!

         

            // runtime error:

            // *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionary0 setObject:forKeyedSubscript:]: unrecognized selector sent to instance

        ....

         

        originally rdar://49775697

        plus FB6447069, this time against Xcode

        • Re: NSDictionary != NSMutableDictionary
          yetanothermeagain Level 1 Level 1 (0 points)

          not even the above, even this:

           

          void foo(NSMutableDictionary** mutableDictionary) {

              (*mutableDictionary)[@"hello"] = @"world";

          }

          ...

              NSObject* whatever = [NSObject new];

              foo(&whatever); // no compilation error or warning here! obvious runtime crash down the road

           

          looks like any superclass pointer causes this behavior. quite dangerous behaviour.

           

          Animal -> Dog -> Labrador

           

          void labradors_only_here_please(Labrador** labrador) {

              [*labrador whatever_only_labradors_can_do];

          }

           

          Dog* generic_dog = [Dog new];

          labradors_only_here_please(&generic_dog) // ok cap, no problem... boom, crash

          • Re: NSDictionary != NSMutableDictionary
            eskimo Apple Staff Apple Staff (11,485 points)

            I submitted a bug about it, but the bug returned with "works with clang-1001.0.46.3 which is part of Xcode 10.2".

            I think you misinterpreted that response.  I just had a look at the state of your bug (r. 49775697) and it’s definitely still open and being treated as a bug by the compiler folks.

            ps The fact that the warning is not emitted in the ARC case is likely to be the result of the compiler taking a different code path in order to handle one of the many complexities of ARC.

            Share and Enjoy

            Quinn “The Eskimo!”
            Apple Developer Relations, Developer Technical Support, Core OS/Hardware
            let myEmail = "eskimo" + "1" + "@apple.com"