From 8d743ac19a1b0c15deccfb14525eaeef56b4135b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 2 Jan 2018 14:28:10 +0200 Subject: Fix few undefined behavior (ubsan) bugs --- build2/function.hxx | 97 +++++++++++++++++++++++++++-------------------------- 1 file changed, 49 insertions(+), 48 deletions(-) (limited to 'build2/function.hxx') diff --git a/build2/function.hxx b/build2/function.hxx index 7507bec..45fe4e8 100644 --- a/build2/function.hxx +++ b/build2/function.hxx @@ -46,7 +46,8 @@ namespace build2 // are conceptually "moved" and can be reused by the implementation. // // A function can also optionally receive the current scope by having the - // first argument of the const scope& type. + // first argument of the const scope* type. It may be NULL is the function + // is called out of any scope (e.g., command line). // // Normally functions come in families that share a common qualification // (e.g., string. or path.). The function_family class is a "registrar" @@ -67,7 +68,7 @@ namespace build2 // struct function_overload; - using function_impl = value (const scope&, + using function_impl = value (const scope*, vector_view, const function_overload&); @@ -150,7 +151,7 @@ namespace build2 erase (iterator i) {map_.erase (i);} value - call (const scope& base, + call (const scope* base, const string& name, vector_view args, const location& l) const @@ -164,7 +165,7 @@ namespace build2 // functions. // pair - try_call (const scope& base, + try_call (const scope* base, const string& name, vector_view args, const location& l) const @@ -193,7 +194,7 @@ namespace build2 private: pair - call (const scope&, + call (const scope*, const string&, vector_view, const location&, @@ -215,7 +216,7 @@ namespace build2 // exceptions), you would normally call the default implementation. // static value - default_thunk (const scope&, vector_view, const function_overload&); + default_thunk (const scope*, vector_view, const function_overload&); // A function family uses a common qualification (though you can pass // empty string to supress it). For an unqualified name (doesn't not @@ -419,12 +420,12 @@ namespace build2 // struct data { - value (*const thunk) (const scope&, vector_view, const void*); + value (*const thunk) (const scope*, vector_view, const void*); R (*const impl) (A...); }; static value - thunk (const scope&, vector_view args, const void* d) + thunk (const scope*, vector_view args, const void* d) { return thunk (move (args), static_cast (d)->impl, @@ -448,16 +449,16 @@ namespace build2 // argument. // template - struct function_cast + struct function_cast { struct data { - value (*const thunk) (const scope&, vector_view, const void*); - R (*const impl) (const scope&, A...); + value (*const thunk) (const scope*, vector_view, const void*); + R (*const impl) (const scope*, A...); }; static value - thunk (const scope& base, vector_view args, const void* d) + thunk (const scope* base, vector_view args, const void* d) { return thunk (base, move (args), static_cast (d)->impl, @@ -466,8 +467,8 @@ namespace build2 template static value - thunk (const scope& base, vector_view args, - R (*impl) (const scope&, A...), + thunk (const scope* base, vector_view args, + R (*impl) (const scope*, A...), std::index_sequence) { return value ( @@ -484,12 +485,12 @@ namespace build2 { struct data { - value (*const thunk) (const scope&, vector_view, const void*); + value (*const thunk) (const scope*, vector_view, const void*); void (*const impl) (A...); }; static value - thunk (const scope&, vector_view args, const void* d) + thunk (const scope*, vector_view args, const void* d) { thunk (move (args), static_cast (d)->impl, @@ -508,16 +509,16 @@ namespace build2 }; template - struct function_cast + struct function_cast { struct data { - value (*const thunk) (const scope&, vector_view, const void*); - void (*const impl) (const scope&, A...); + value (*const thunk) (const scope*, vector_view, const void*); + void (*const impl) (const scope*, A...); }; static value - thunk (const scope& base, vector_view args, const void* d) + thunk (const scope* base, vector_view args, const void* d) { thunk (base, move (args), static_cast (d)->impl, @@ -527,8 +528,8 @@ namespace build2 template static void - thunk (const scope& base, vector_view args, - void (*impl) (const scope&, A...), + thunk (const scope* base, vector_view args, + void (*impl) (const scope*, A...), std::index_sequence) { impl (base, @@ -544,12 +545,12 @@ namespace build2 { struct data { - value (*const thunk) (const scope&, vector_view, const void*); + value (*const thunk) (const scope*, vector_view, const void*); R (L::*const impl) (A...) const; }; static value - thunk (const scope&, vector_view args, const void* d) + thunk (const scope*, vector_view args, const void* d) { return thunk (move (args), static_cast (d)->impl, @@ -572,16 +573,16 @@ namespace build2 }; template - struct function_cast_lamb + struct function_cast_lamb { struct data { - value (*const thunk) (const scope&, vector_view, const void*); - R (L::*const impl) (const scope&, A...) const; + value (*const thunk) (const scope*, vector_view, const void*); + R (L::*const impl) (const scope*, A...) const; }; static value - thunk (const scope& base, vector_view args, const void* d) + thunk (const scope* base, vector_view args, const void* d) { return thunk (base, move (args), static_cast (d)->impl, @@ -590,8 +591,8 @@ namespace build2 template static value - thunk (const scope& base, vector_view args, - R (L::*impl) (const scope&, A...) const, + thunk (const scope* base, vector_view args, + R (L::*impl) (const scope*, A...) const, std::index_sequence) { const L* l (nullptr); // Undefined behavior. @@ -608,12 +609,12 @@ namespace build2 { struct data { - value (*const thunk) (const scope&, vector_view, const void*); + value (*const thunk) (const scope*, vector_view, const void*); void (L::*const impl) (A...) const; }; static value - thunk (const scope&, vector_view args, const void* d) + thunk (const scope*, vector_view args, const void* d) { thunk (move (args), static_cast (d)->impl, @@ -635,16 +636,16 @@ namespace build2 }; template - struct function_cast_lamb + struct function_cast_lamb { struct data { - value (*const thunk) (const scope&, vector_view, const void*); - void (L::*const impl) (const scope&, A...) const; + value (*const thunk) (const scope*, vector_view, const void*); + void (L::*const impl) (const scope*, A...) const; }; static value - thunk (const scope& base, vector_view args, const void* d) + thunk (const scope* base, vector_view args, const void* d) { thunk (base, move (args), static_cast (d)->impl, @@ -654,8 +655,8 @@ namespace build2 template static void - thunk (const scope& base, vector_view args, - void (L::*impl) (const scope&, A...) const, + thunk (const scope* base, vector_view args, + void (L::*impl) (const scope*, A...) const, std::index_sequence) { const L* l (nullptr); @@ -673,12 +674,12 @@ namespace build2 { struct data { - value (*const thunk) (const scope&, vector_view, const void*); + value (*const thunk) (const scope*, vector_view, const void*); R (T::*const impl) () const; }; static value - thunk (const scope&, vector_view args, const void* d) + thunk (const scope*, vector_view args, const void* d) { auto mf (static_cast (d)->impl); return value ((function_arg::cast (&args[0]).*mf) ()); @@ -690,12 +691,12 @@ namespace build2 { struct data { - value (*const thunk) (const scope&, vector_view, const void*); + value (*const thunk) (const scope*, vector_view, const void*); void (T::*const impl) () const; }; static value - thunk (const scope&, vector_view args, const void* d) + thunk (const scope*, vector_view args, const void* d) { auto mf (static_cast (d)->impl); (function_arg::cast (args[0]).*mf) (); @@ -710,12 +711,12 @@ namespace build2 { struct data { - value (*const thunk) (const scope&, vector_view, const void*); + value (*const thunk) (const scope*, vector_view, const void*); R T::*const impl; }; static value - thunk (const scope&, vector_view args, const void* d) + thunk (const scope*, vector_view args, const void* d) { auto dm (static_cast (d)->impl); return value (move (function_arg::cast (&args[0]).*dm)); @@ -747,10 +748,10 @@ namespace build2 template void - operator= (R (*impl) (const scope&, A...)) && + operator= (R (*impl) (const scope*, A...)) && { using args = function_args; - using cast = function_cast; + using cast = function_cast; insert (move (name), function_overload ( @@ -797,10 +798,10 @@ namespace build2 template void - coerce_lambda (R (L::*op) (const scope&, A...) const) && + coerce_lambda (R (L::*op) (const scope*, A...) const) && { using args = function_args; - using cast = function_cast_lamb; + using cast = function_cast_lamb; insert (move (name), function_overload ( -- cgit v1.1