When split-init is used to initialize a variable whose type is
generic, the compiler fails to detect if the variable is initialized
with different instantiations of the generic type in different
branches of a conditional.
Steps to Reproduce
Source Code:
record R {
param p;
var i: int;
}
proc foo(r1: R, r2: R) {
var ret: R;
if r1.i > 0 {
ret = r1;
} else {
ret = r2;
}
return ret;
}
var rint = new R(1, 42);
var rstr = new R("frog", 43);
var v1 = foo(rint, rstr);
writeln(v1, ": ", v1.type:string);
var v2 = foo(rstr, rint);
writeln(v2, ": ", v2.type:string);
I believe this shouldn't compile because ret is initialized with
different types in the two branches of the conditional (when r1 and
r2 are of different concrete types, as they are here).
However,
(i = 42): R("frog")
(i = 43): R(1)
(Beyond incorrectly compiling, the "wrong" type is resolved in each
case; the R with i==42 was rint: R(1).)
Variations:
Making R generic over a field instead of a param means the mixed types can result in memory errors:
record R {
var g;
var i: int;
}
proc foo(r1: R, r2: R) {
var ret: R;
if r1.i > 0 {
ret = r1;
} else {
ret = r2;
}
return ret;
}
var r11t = new R(1, 42);
var r12t = new R("frog", 43);
var v1 = foo(r11t, r12t);
writeln(v1, ": ", v1.type:string);
var v2 = foo(r12t, r11t);
writeln(v2, ": ", v2.type:string);
./foo -nl 1
*** Caught a fatal signal (proc 0): SIGSEGV(11)
NOTICE: Before reporting bugs, run with GASNET_BACKTRACE=1 in the environment to generate a backtrace.
NOTICE: We recommend linking the debug version of GASNet to assist you in resolving this application issue.
backtraces
*** Caught a fatal signal (proc 0): SIGSEGV(11)
NOTICE: We recommend linking the debug version of GASNet to assist you in resolving this application issue.
[0] Invoking GDB for backtrace...
[0] /usr/bin/gdb -nx -batch -x /tmp/gasnet_e1001P '/home/fortytwo/src/chapel/foo_real' 107364
[0] [New LWP 107365]
[0] [New LWP 107366]
[0] [New LWP 107367]
[0] [New LWP 107368]
[0] [New LWP 107369]
[0] [New LWP 107370]
[0] [New LWP 107371]
[0] [New LWP 107372]
[0] [New LWP 107373]
[0] futex_wait (private=0, expected=2, futex_word=0x7ffd9288bb20) at ../sysdeps/nptl/futex-internal.h:146
[0] Id Target Id Frame
[0] * 1 LWP 107364 "foo_real" futex_wait (private=0, expected=2, futex_word=0x7ffd9288bb20) at ../sysdeps/nptl/futex-internal.h:146
[0] 2 LWP 107365 "foo_real" 0x00007fe306f0c87f in __GI___wait4 (pid=107374, stat_loc=stat_loc@entry=0x7fe2fa5f7468, options=options@entry=0, usage=usage@entry=0x0) at ../sysdeps/unix/sysv/linux/wait4.c:30
[0] 3 LWP 107366 "foo_real" __futex_abstimed_wait_common64 (cancel=true, private=0, abstime=0x7fe2ffffec70, clockid=32739, expected=0, futex_word=0x7fe304ce61b8) at ../sysdeps/nptl/futex-internal.c:74
[0] 4 LWP 107367 "foo_real" __futex_abstimed_wait_common64 (cancel=true, private=0, abstime=0x7fe2ff7fdc70, clockid=32739, expected=0, futex_word=0x7fe304ce62b8) at ../sysdeps/nptl/futex-internal.c:74
[0] 5 LWP 107368 "foo_real" __futex_abstimed_wait_common64 (cancel=true, private=0, abstime=0x7fe2feffcc70, clockid=32738, expected=0, futex_word=0x7fe304ce63b8) at ../sysdeps/nptl/futex-internal.c:74
[0] 6 LWP 107369 "foo_real" __futex_abstimed_wait_common64 (cancel=true, private=0, abstime=0x7fe2fe7fbc70, clockid=32738, expected=0, futex_word=0x7fe304ce64b8) at ../sysdeps/nptl/futex-internal.c:74
[0] 7 LWP 107370 "foo_real" __futex_abstimed_wait_common64 (cancel=true, private=0, abstime=0x7fe2fdffac70, clockid=32738, expected=0, futex_word=0x7fe304ce65b8) at ../sysdeps/nptl/futex-internal.c:74
[0] 8 LWP 107371 "foo_real" __futex_abstimed_wait_common64 (cancel=true, private=0, abstime=0x7fe2fd7f9c70, clockid=32738, expected=0, futex_word=0x7fe304ce66b8) at ../sysdeps/nptl/futex-internal.c:74
[0] 9 LWP 107372 "foo_real" __futex_abstimed_wait_common64 (cancel=true, private=0, abstime=0x7fe2fcff8c70, clockid=32738, expected=0, futex_word=0x7fe304ce67b8) at ../sysdeps/nptl/futex-internal.c:74
[0] 10 LWP 107373 "foo_real" 0x00007fe306f2b29b in sched_yield () at ../sysdeps/unix/syscall-template.S:120
[0]
[0] Thread 10 (LWP 107373 "foo_real"):
[0] #0 0x00007fe306f2b29b in sched_yield () at ../sysdeps/unix/syscall-template.S:120
[0] #1 0x000055822b358cf3 in chpl_task_yield () at tasks-qthreads.c:179
[0] #2 0x000055822b35d4eb in polling (x=0x0) at comm-gasnet.c:752
[0] #3 0x000055822b359fad in comm_task_wrapper (arg=0x55822b520320 ) at tasks-qthreads.c:755
[0] #4 0x00007fe3073a6450 in start_thread (arg=0x7fe2fc7f8640) at pthread_create.c:473
[0] #5 0x00007fe306f46d53 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
[0]
[0] Thread 9 (LWP 107372 "foo_real"):
[0] #0 __futex_abstimed_wait_common64 (cancel=true, private=0, abstime=0x7fe2fcff8c70, clockid=32738, expected=0, futex_word=0x7fe304ce67b8) at ../sysdeps/nptl/futex-internal.c:74
[0] #1 __GI___futex_abstimed_wait_cancelable64 (futex_word=futex_word@entry=0x7fe304ce67b8, expected=expected@entry=0, clockid=clockid@entry=0, abstime=abstime@entry=0x7fe2fcff8c70, private=private@entry=0) at ../sysdeps/nptl/futex-internal.c:123
[0] #2 0x00007fe3073ac99e in __pthread_cond_wait_common (abstime=0x7fe2fcff8c70, clockid=0, mutex=0x7fe304ce67c0, cond=0x7fe304ce6790) at pthread_cond_wait.c:504
[0] #3 __pthread_cond_timedwait (cond=0x7fe304ce6790, mutex=0x7fe304ce67c0, abstime=0x7fe2fcff8c70) at pthread_cond_wait.c:646
[0] #4 0x000055822b452605 in qt_scheduler_get_thread (q=0x7fe304ce6700, UNUSED_qc=0x0, UNUSED_active=1 '\001') at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/threadqueues/nemesis_threadqueues.c:397
[0] #5 0x000055822b44c598 in qthread_master (arg=0x7fe304c172a0) at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/qthread.c:473
[0] #6 0x00007fe3073a6450 in start_thread (arg=0x7fe2fcff9640) at pthread_create.c:473
[0] #7 0x00007fe306f46d53 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
[0]
[0] Thread 8 (LWP 107371 "foo_real"):
[0] #0 __futex_abstimed_wait_common64 (cancel=true, private=0, abstime=0x7fe2fd7f9c70, clockid=32738, expected=0, futex_word=0x7fe304ce66b8) at ../sysdeps/nptl/futex-internal.c:74
[0] #1 __GI___futex_abstimed_wait_cancelable64 (futex_word=futex_word@entry=0x7fe304ce66b8, expected=expected@entry=0, clockid=clockid@entry=0, abstime=abstime@entry=0x7fe2fd7f9c70, private=private@entry=0) at ../sysdeps/nptl/futex-internal.c:123
[0] #2 0x00007fe3073ac99e in __pthread_cond_wait_common (abstime=0x7fe2fd7f9c70, clockid=0, mutex=0x7fe304ce66c0, cond=0x7fe304ce6690) at pthread_cond_wait.c:504
[0] #3 __pthread_cond_timedwait (cond=0x7fe304ce6690, mutex=0x7fe304ce66c0, abstime=0x7fe2fd7f9c70) at pthread_cond_wait.c:646
[0] #4 0x000055822b452605 in qt_scheduler_get_thread (q=0x7fe304ce6600, UNUSED_qc=0x0, UNUSED_active=1 '\001') at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/threadqueues/nemesis_threadqueues.c:397
[0] #5 0x000055822b44c598 in qthread_master (arg=0x7fe304c17240) at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/qthread.c:473
[0] #6 0x00007fe3073a6450 in start_thread (arg=0x7fe2fd7fa640) at pthread_create.c:473
[0] #7 0x00007fe306f46d53 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
[0]
[0] Thread 7 (LWP 107370 "foo_real"):
[0] #0 __futex_abstimed_wait_common64 (cancel=true, private=0, abstime=0x7fe2fdffac70, clockid=32738, expected=0, futex_word=0x7fe304ce65b8) at ../sysdeps/nptl/futex-internal.c:74
[0] #1 __GI___futex_abstimed_wait_cancelable64 (futex_word=futex_word@entry=0x7fe304ce65b8, expected=expected@entry=0, clockid=clockid@entry=0, abstime=abstime@entry=0x7fe2fdffac70, private=private@entry=0) at ../sysdeps/nptl/futex-internal.c:123
[0] #2 0x00007fe3073ac99e in __pthread_cond_wait_common (abstime=0x7fe2fdffac70, clockid=0, mutex=0x7fe304ce65c0, cond=0x7fe304ce6590) at pthread_cond_wait.c:504
[0] #3 __pthread_cond_timedwait (cond=0x7fe304ce6590, mutex=0x7fe304ce65c0, abstime=0x7fe2fdffac70) at pthread_cond_wait.c:646
[0] #4 0x000055822b452605 in qt_scheduler_get_thread (q=0x7fe304ce6500, UNUSED_qc=0x0, UNUSED_active=1 '\001') at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/threadqueues/nemesis_threadqueues.c:397
[0] #5 0x000055822b44c598 in qthread_master (arg=0x7fe304c171e0) at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/qthread.c:473
[0] #6 0x00007fe3073a6450 in start_thread (arg=0x7fe2fdffb640) at pthread_create.c:473
[0] #7 0x00007fe306f46d53 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
[0]
[0] Thread 6 (LWP 107369 "foo_real"):
[0] #0 __futex_abstimed_wait_common64 (cancel=true, private=0, abstime=0x7fe2fe7fbc70, clockid=32738, expected=0, futex_word=0x7fe304ce64b8) at ../sysdeps/nptl/futex-internal.c:74
[0] #1 __GI___futex_abstimed_wait_cancelable64 (futex_word=futex_word@entry=0x7fe304ce64b8, expected=expected@entry=0, clockid=clockid@entry=0, abstime=abstime@entry=0x7fe2fe7fbc70, private=private@entry=0) at ../sysdeps/nptl/futex-internal.c:123
[0] #2 0x00007fe3073ac99e in __pthread_cond_wait_common (abstime=0x7fe2fe7fbc70, clockid=0, mutex=0x7fe304ce64c0, cond=0x7fe304ce6490) at pthread_cond_wait.c:504
[0] #3 __pthread_cond_timedwait (cond=0x7fe304ce6490, mutex=0x7fe304ce64c0, abstime=0x7fe2fe7fbc70) at pthread_cond_wait.c:646
[0] #4 0x000055822b452605 in qt_scheduler_get_thread (q=0x7fe304ce6400, UNUSED_qc=0x0, UNUSED_active=1 '\001') at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/threadqueues/nemesis_threadqueues.c:397
[0] #5 0x000055822b44c598 in qthread_master (arg=0x7fe304c17180) at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/qthread.c:473
[0] #6 0x00007fe3073a6450 in start_thread (arg=0x7fe2fe7fc640) at pthread_create.c:473
[0] #7 0x00007fe306f46d53 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
[0]
[0] Thread 5 (LWP 107368 "foo_real"):
[0] #0 __futex_abstimed_wait_common64 (cancel=true, private=0, abstime=0x7fe2feffcc70, clockid=32738, expected=0, futex_word=0x7fe304ce63b8) at ../sysdeps/nptl/futex-internal.c:74
[0] #1 __GI___futex_abstimed_wait_cancelable64 (futex_word=futex_word@entry=0x7fe304ce63b8, expected=expected@entry=0, clockid=clockid@entry=0, abstime=abstime@entry=0x7fe2feffcc70, private=private@entry=0) at ../sysdeps/nptl/futex-internal.c:123
[0] #2 0x00007fe3073ac99e in __pthread_cond_wait_common (abstime=0x7fe2feffcc70, clockid=0, mutex=0x7fe304ce63c0, cond=0x7fe304ce6390) at pthread_cond_wait.c:504
[0] #3 __pthread_cond_timedwait (cond=0x7fe304ce6390, mutex=0x7fe304ce63c0, abstime=0x7fe2feffcc70) at pthread_cond_wait.c:646
[0] #4 0x000055822b452605 in qt_scheduler_get_thread (q=0x7fe304ce6300, UNUSED_qc=0x0, UNUSED_active=1 '\001') at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/threadqueues/nemesis_threadqueues.c:397
[0] #5 0x000055822b44c598 in qthread_master (arg=0x7fe304c17120) at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/qthread.c:473
[0] #6 0x00007fe3073a6450 in start_thread (arg=0x7fe2feffd640) at pthread_create.c:473
[0] #7 0x00007fe306f46d53 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
[0]
[0] Thread 4 (LWP 107367 "foo_real"):
[0] #0 __futex_abstimed_wait_common64 (cancel=true, private=0, abstime=0x7fe2ff7fdc70, clockid=32739, expected=0, futex_word=0x7fe304ce62b8) at ../sysdeps/nptl/futex-internal.c:74
[0] #1 __GI___futex_abstimed_wait_cancelable64 (futex_word=futex_word@entry=0x7fe304ce62b8, expected=expected@entry=0, clockid=clockid@entry=0, abstime=abstime@entry=0x7fe2ff7fdc70, private=private@entry=0) at ../sysdeps/nptl/futex-internal.c:123
[0] #2 0x00007fe3073ac99e in __pthread_cond_wait_common (abstime=0x7fe2ff7fdc70, clockid=0, mutex=0x7fe304ce62c0, cond=0x7fe304ce6290) at pthread_cond_wait.c:504
[0] #3 __pthread_cond_timedwait (cond=0x7fe304ce6290, mutex=0x7fe304ce62c0, abstime=0x7fe2ff7fdc70) at pthread_cond_wait.c:646
[0] #4 0x000055822b452605 in qt_scheduler_get_thread (q=0x7fe304ce6200, UNUSED_qc=0x0, UNUSED_active=1 '\001') at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/threadqueues/nemesis_threadqueues.c:397
[0] #5 0x000055822b44c598 in qthread_master (arg=0x7fe304c170c0) at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/qthread.c:473
[0] #6 0x00007fe3073a6450 in start_thread (arg=0x7fe2ff7fe640) at pthread_create.c:473
[0] #7 0x00007fe306f46d53 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
[0]
[0] Thread 3 (LWP 107366 "foo_real"):
[0] #0 __futex_abstimed_wait_common64 (cancel=true, private=0, abstime=0x7fe2ffffec70, clockid=32739, expected=0, futex_word=0x7fe304ce61b8) at ../sysdeps/nptl/futex-internal.c:74
[0] #1 __GI___futex_abstimed_wait_cancelable64 (futex_word=futex_word@entry=0x7fe304ce61b8, expected=expected@entry=0, clockid=clockid@entry=0, abstime=abstime@entry=0x7fe2ffffec70, private=private@entry=0) at ../sysdeps/nptl/futex-internal.c:123
[0] #2 0x00007fe3073ac99e in __pthread_cond_wait_common (abstime=0x7fe2ffffec70, clockid=0, mutex=0x7fe304ce61c0, cond=0x7fe304ce6190) at pthread_cond_wait.c:504
[0] #3 __pthread_cond_timedwait (cond=0x7fe304ce6190, mutex=0x7fe304ce61c0, abstime=0x7fe2ffffec70) at pthread_cond_wait.c:646
[0] #4 0x000055822b452605 in qt_scheduler_get_thread (q=0x7fe304ce6100, UNUSED_qc=0x0, UNUSED_active=1 '\001') at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/threadqueues/nemesis_threadqueues.c:397
[0] #5 0x000055822b44c598 in qthread_master (arg=0x7fe304c17060) at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/qthread.c:473
[0] #6 0x00007fe3073a6450 in start_thread (arg=0x7fe2fffff640) at pthread_create.c:473
[0] #7 0x00007fe306f46d53 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
[0]
[0] Thread 2 (LWP 107365 "foo_real"):
[0] #0 0x00007fe306f0c87f in __GI___wait4 (pid=107374, stat_loc=stat_loc@entry=0x7fe2fa5f7468, options=options@entry=0, usage=usage@entry=0x0) at ../sysdeps/unix/sysv/linux/wait4.c:30
[0] #1 0x00007fe306f0c7fb in __GI___waitpid (pid=, stat_loc=stat_loc@entry=0x7fe2fa5f7468, options=options@entry=0) at waitpid.c:38
[0] #2 0x00007fe306e7e6ab in do_system (line=) at ../sysdeps/posix/system.c:172
[0] #3 0x000055822b393dc4 in gasneti_bt_gdb ()
[0] #4 0x000055822b398647 in gasneti_print_backtrace ()
[0] #5 0x000055822b27729a in gasneti_defaultSignalHandler ()
[0] #6
[0] #7 __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:294
[0] #8 0x000055822b36f7dc in chpl_memcpy (dest=0x7fe304dae005, src=0x1100000004, num=1) at ../../include/chpl-mem.h:163
[0] #9 0x000055822b36ffeb in qio_channel_write_amt (threadsafe=0, ch=0x7fe304c0d300, ptr=0x1100000004, len=1) at ../../include/qio/qio.h:1060
[0] #10 0x000055822b375764 in qio_channel_print_string (threadsafe=0, ch=0x7fe304c0d300, ptr=0x1100000004 , len=1) at qio_formatted.c:1584
[0] #11 0x000055822b329935 in _write_text_internal_chpl ()
[0] #12 0x000055822b32f2e7 in _write_one_internal_chpl2 ()
[0] #13 0x000055822b32e231 in _writeOne_chpl3 ()
[0] #14 0x000055822b332d48 in on_fn_chpl101 ()
[0] #15 0x000055822b331045 in writeIt_chpl2 ()
[0] #16 0x000055822b311f8e in writeThisFieldsDefaultImpl_chpl2 ()
[0] #17 0x000055822b315d8e in writeThisDefaultImpl_chpl ()
[0] #18 0x000055822b32fce3 in _write_one_internal_chpl5 ()
[0] #19 0x000055822b32dc09 in _writeOne_chpl4 ()
[0] #20 0x000055822b3380d5 in on_fn_chpl105 ()
[0] #21 0x000055822b339ca8 in writeln_chpl4 ()
[0] #22 0x000055822b3166bd in writeln_chpl2 ()
[0] #23 0x000055822b30f1a3 in chpl.init_foo ()
[0] #24 0x000055822b30f751 in chpl_gen_main ()
[0] #25 0x000055822b354135 in chpl_executable_init () at chpl-init.c:321
[0] #26 0x000055822b359f69 in chapel_wrapper (arg=0x7fe305859040) at tasks-qthreads.c:740
[0] #27 0x000055822b44f253 in qthread_wrapper (ptr=0x7fe305859000) at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/qthread.c:2175
[0] #28 0x0000000000000000 in ?? ()
[0]
[0] Thread 1 (LWP 107364 "foo_real"):
[0] #0 futex_wait (private=0, expected=2, futex_word=0x7ffd9288bb20) at ../sysdeps/nptl/futex-internal.h:146
[0] #1 __lll_lock_wait (futex=futex@entry=0x7ffd9288bb20, private=0) at lowlevellock.c:52
[0] #2 0x00007fe3073a8733 in __GI___pthread_mutex_lock (mutex=0x7ffd9288bb20) at ../nptl/pthread_mutex_lock.c:80
[0] #3 0x000055822b449d82 in qthread_feb_blocker_func (dest=0x0, src=0x55822b520310 , t=READFF) at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/feb.c:249
[0] #4 0x000055822b44b2bd in qthread_readFF (dest=0x0, src=0x55822b520310 ) at /home/fortytwo/src/chapel/third-party/qthread/qthread-src/src/feb.c:1223
[0] #5 0x000055822b35a081 in chpl_task_callMain (chpl_main=0x55822b354112 ) at tasks-qthreads.c:780
[0] #6 0x000055822b346010 in main (argc=3, argv=0x7ffd9288bd48) at main.c:33
[0] [Inferior 1 (process 107364) detached]
(g =
If foo() returns r1 or r2 directly instead of involving ret,
the compiler reports that it can't determine the return type of
foo().
If ret is declared purely generic, var ret;, split-init recognizes
the problem:
foo.chpl:6: In function 'foo':
foo.chpl:11: error: Split initialization uses multiple types; another initialization has type R(int(64)) but this initialization has type R(string)
foo.chpl:19: called as foo(r1: R(int(64)), r2: R(string))
note: generic instantiations are underlined in the above callstack
foo.chpl:6: In function 'foo':
foo.chpl:11: note: Split initialization uses multiple types; another initialization has type R(string) but this initialization has type R(int(64))
foo.chpl:22: called as foo(r1: R(string), r2: R(int(64)))
note: generic instantiations are underlined in the above callstack
Wow, that's a pretty weird one, thanks for filing it, Paul. Tagging @mppf due to the link to split initialization and @e-kayrakli due to the implication that OrderedSet may contain a time bomb.
Summary of Problem
When split-init is used to initialize a variable whose type is generic, the compiler fails to detect if the variable is initialized with different instantiations of the generic type in different branches of a conditional.
Steps to Reproduce
Source Code:
I believe this shouldn't compile because
ret
is initialized with different types in the two branches of the conditional (whenr1
andr2
are of different concrete types, as they are here).However,
(Beyond incorrectly compiling, the "wrong" type is resolved in each case; the
R
withi==42
wasrint: R(1)
.)Variations:
Making
R
generic over a field instead of a param means the mixed types can result in memory errors:backtraces
If
foo()
returnsr1
orr2
directly instead of involvingret
, the compiler reports that it can't determine the return type offoo()
.If
ret
is declared purely generic,var ret;
, split-init recognizes the problem:This was inspired by the third point in
https://github.com/chapel-lang/chapel/pull/18661#issuecomment-955138853
I believe
orderedSet.^
won't compile when this is fixed. (When it's passed arguments with different comparators.)Associated Future Test(s):
None yet.
Configuration Information